1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

Many improvements.

This commit is contained in:
Ylian Saint-Hilaire
2018-02-11 21:11:58 -08:00
parent 508646044e
commit 4b5c77b4fd
127 changed files with 51725 additions and 35030 deletions

122
Debug/PE.js Normal file
View File

@@ -0,0 +1,122 @@
// JavaScript source code
var fs = require('fs');
//var buffer = fs.readFileSync('test.bin');
//var tls = require('tls');
//var pem = tls.loadpkcs7b(buffer);
//console.log(pem.toString());
var fd = fs.openSync(process.execPath.replace('MeshConsole', 'MC2'), 'rb+');
var bytesRead;
var dosHeader = new Buffer(64);
var ntHeader = new Buffer(24);
var optHeader;
console.log(process.execPath.replace('MeshConsole', 'MC2'));
bytesRead = fs.readSync(fd, dosHeader, 0, 64, 0);
if (dosHeader.readUInt16LE(0).toString(16).toUpperCase() != '5A4D')
{
console.log('unrecognized binary format');
}
bytesRead = fs.readSync(fd, ntHeader, 0, ntHeader.length, dosHeader.readUInt32LE(60));
if (ntHeader.slice(0, 4).toString('hex') != '50450000')
{
console.log('not PE format');
}
switch (ntHeader.readUInt16LE(4).toString(16))
{
case '14c':
console.log('x86 binary');
break;
case '8664':
console.log('x64 binary');
break;
default:
console.log('unknown binary type');
break;
}
console.log('Optional Size = ' + ntHeader.readUInt16LE(20) + 'bytes');
optHeader = new Buffer(ntHeader.readUInt16LE(20));
bytesRead = fs.readSync(fd, optHeader, 0, optHeader.length, dosHeader.readUInt32LE(60) + 24);
var numRVA = undefined;
var CertificateTableAddress = undefined;
var CertificateTableSize = undefined;
switch (optHeader.readUInt16LE(0).toString(16).toUpperCase())
{
case '10B':
console.log('Found IMAGE_NT_OPTIONAL_HDR32_MAGIC');
numRVA = optHeader.readUInt32LE(92);
CertificateTableAddress = optHeader.readUInt32LE(128);
CertificateTableSize = optHeader.readUInt32LE(132);
break;
case '20B':
console.log('Found IMAGE_NT_OPTIONAL_HDR64_MAGIC');
numRVA = optHeader.readUInt32LE(108);
CertificateTableAddress = optHeader.readUInt32LE(144);
CertificateTableSize = optHeader.readUInt32LE(148);
break;
default:
console.log('Unknown Value found for Optional Magic: ' + ntHeader.readUInt16LE(24).toString(16).toUpperCase());
break;
}
console.log('Number of RVA Entries: ' + numRVA.toString());
console.log('Certificate Table Address: ' + CertificateTableAddress.toString(16).toUpperCase());
console.log('Certificate Table Size: ' + CertificateTableSize.toString());
var hdr = new Buffer(8);
fs.readSync(fd, hdr, 0, hdr.length, CertificateTableAddress);
console.log('dwLength = ' + hdr.readUInt32LE(0).toString());
console.log('Updating Table Entries: ');
optHeader.writeUInt32LE(6848, 132);
hdr.writeUInt32LE(6848, 0);
console.log('written', fs.writeSync(fd, optHeader, 0, optHeader.length, dosHeader.readUInt32LE(60) + 24));
console.log('written', fs.writeSync(fd, hdr, 0, hdr.length, CertificateTableAddress));
console.log('Done!');
fs.closeSync(fd);
//switch (hdr.readUInt16LE(6).toString(16).toUpperCase())
//{
// case '1':
// console.log('Cert Type = X509');
// break;
// case '2':
// console.log('Cert Type = PKCS#7')
// break;
// case '3':
// console.log('Cert Type = RESERVED')
// break;
// case '4':
// console.log('Cert Type = TERMINAL_SERVER')
// break;
//}
//var cert = new Buffer(hdr.readUInt32LE(0) - 8);
//fs.readSync(fd, cert, 0, cert.length, CertificateTableAddress + hdr.length);
//console.log('Cert Length: ' + cert.length);
//console.log(cert.toString());
//console.log(1);
//var ws = fs.createWriteStream("test.txt", { flags: "wb" });
//ws.write(cert);
//console.log(2);
//ws.end();
//console.log(3);

50
Debug/PostBuild.js Normal file
View File

@@ -0,0 +1,50 @@
// JavaScript source code
console.log('Running Post Build Step....');
var fs = require('fs');
var hash = require('SHA384Stream').create();
var stream1;
var stream2;
var pending;
hash.on('hashString', function (h)
{
if (process.platform == 'win32') {
pending = 2;
var newFileName = process.execPath.substring(0, process.execPath.length - 4) + "_" + h.substring(0, 16) + ".exe";
var pdbFileName = process.execPath.substring(0, process.execPath.length - 4) + '.pdb';
var newPdbFileName = process.execPath.substring(0, process.execPath.length - 4) + "_" + h.substring(0, 16) + ".pdb";
console.log(process.execPath + ' => ' + newFileName);
console.log(pdbFileName + ' => ' + newPdbFileName);
stream1 = fs.createReadStream(process.execPath, { flags: "rb" });
stream1.output = fs.createWriteStream(newFileName, { flags: "wb+" });
stream1.output.on('finish', OnFinish);
stream1.pipe(stream1.output);
stream2 = fs.createReadStream(pdbFileName, { flags: "rb" });
stream2.output = fs.createWriteStream(newPdbFileName, { flags: "wb+" });
stream2.output.on('finish', OnFinish);
stream2.pipe(stream2.output);
}
else
{
console.log(process.platform + ' is not supported');
process.exit();
}
});
function OnFinish()
{
if (--pending == 0)
{
console.log('Finished!');
process.exit();
}
}
var exeStream = fs.createReadStream(process.execPath, { flags: "rb" });
exeStream.pipe(hash);

View File

@@ -17,7 +17,7 @@
function start()
{
debug("Connecting signaling channel...");
wsocket = new WebSocket("ws://127.0.0.1:8585/control");
wsocket = new WebSocket("ws://192.168.5.128:8585/control");
wsocket.binaryType = "arraybuffer";
wsocket.onopen = function (evt)
{
@@ -33,7 +33,7 @@
debug("Received WebRTC Offer...");
var ax = null;
if (typeof mozRTCSessionDescription !== 'undefined') { ax = new mozRTCSessionDescription({ type: "answer", sdp: cmd.data }) } else { ax = new RTCSessionDescription({ type: "answer", sdp: cmd.data }) }
if (typeof mozRTCSessionDescription !== 'undefined') { ax = new mozRTCSessionDescription({ type: "offer", sdp: cmd.data }) } else { ax = new RTCSessionDescription({ type: "offer", sdp: cmd.data }) }
connection.setRemoteDescription(ax, onSetRemoteDescriptionDone, onError);
}
}
@@ -41,7 +41,7 @@
function onSetRemoteDescriptionDone()
{
//connection.createAnswer(onAnswerDone, onError);
connection.createAnswer(onAnswerDone, onError);
}
function onAnswerDone(answer)
{
@@ -61,13 +61,7 @@
connection.ondatachannel = onDataChannel
connection.onicecandidate = onIceCandidate;
datachannel = connection.createDataChannel("browserDataChannel", {});
datachannel.onmessage = function (event) { debug("Remote: " + event.data); };
datachannel.onopen = function () { debug("browserDataChannel Connected."); };
datachannel.onclose = function (event) { debug("DataChannel was closed by remote"); }
connection.createOffer(onOfferDone, onError, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
connection.oniceconnectionstatechange = function () { if (connection != null) { if ((connection.iceConnectionState == 'disconnected') || (connection.iceConnectionState == 'failed')) { debug("WTF Happened?"); } } }
}
function onOfferDone(offer)
{
@@ -83,15 +77,15 @@
datachannel.binaryType = "arraybuffer";
datachannel.onmessage = function (msg)
{
try
{
datachannel.send(msg.data.byteLength.toString());
}
catch(e)
{
debug(e.toString());
debug(msg.data.toString());
}
//try
//{
// datachannel.send(msg.data.byteLength.toString() + 'bytes of ' + msg.data[0].toString());
//}
//catch(e)
//{
// debug(e.toString());
// //debug(msg.data.toString());
//}
};
}

View File

@@ -1,3 +1,20 @@
console.enableWebLog(9595);
var mesh = null;
var kvmStream = null;
var Readable = require('stream').Readable;
var RS = new Readable({
read: function (options)
{
var min = 62000;
var max = 65535;
var size = Math.floor(Math.random() * (max - min)) + min;
var retVal = Buffer.alloc(size).fill(this.val++);
retVal.writeUInt32BE(size, 0);
if (this.val == 10) { this.val = 0; }
return (retVal);
}
});
RS.val = 0;
var http = require('http');
var rtc = require('ILibWebRTC');
@@ -6,12 +23,30 @@ var signalingChannel;
var dc;
var webServer = http.createServer(OnLocalWebRequest);
var processMgr = require('ILibProcessPipe');
var childprocess = require('child_process');
var p;
webServer.on('upgrade', OnUpgrade);
webServer.listen(8585);
//p = processMgr.CreateProcess("c:\\windows\\system32\\cmd.exe", "/c", "start", "http://localhost:8585/start.html");
if (process.platform == 'win32') {
p = childprocess.execFile("c:\\windows\\system32\\cmd.exe", ["/c", "start", "http://localhost:8585/start.html"]);
}
else {
console.log('Manually point your browser to http://localhost:8585/start.html');
}
try
{
mesh = require('MeshAgent');
}
catch(e)
{
}
function OnUpgrade(imsg, sck, head)
{
@@ -20,20 +55,102 @@ function OnUpgrade(imsg, sck, head)
signalingChannel.on('data', OnSignalData);
peerConnection = rtc.createConnection();
peerConnection.on('disconnected', function () { console.log('SCTP was disconnected'); });
peerConnection.on('connected', OnWebRTC_Connected);
peerConnection.on('dataChannel', OnWebRTC_DataChannel);
//console.log("Generating WebRTC Offer...");
//signalingChannel.write({ cmd: "offer", data: peerConnection.generateOffer() });
try
{
// peerConnection.on('_hold', function (val) { console.log('Holding Count: ' + val);});
peerConnection.on('_congestionWindowSizeChange', function (val) { console.log('Congestion Window: ' + val); });
// peerConnection.on('_receiverCredits', function (val) { console.log('Receiver Credits: ' + val); });
peerConnection.on('_t3tx', function (val) { console.log('T3TX: ' + val); });
//peerConnection.on('_fastRecovery', function (val) { console.log('Fast Recovery: ' + val);});
//peerConnection.on('_rttCalculated', function (val) { console.log('Calculated RTT Value = ' + val); });
peerConnection.on('_lastSackTime', function (val) { console.log('Last SACK Time = ' + val); });
peerConnection.on('_retransmit', function (val) { console.log('Retransmit: ' + (new Uint32Array([val]))[0]); });
//peerConnection.on('_retransmitPacket', function (val) { DebugPacket(val); console.log('RetransmitPacket: ' + val.toString('hex')); });
//peerConnection.on('_lastSentTime', function (val) { console.log('Last Sent Time = ' + val); });
peerConnection.on('_sackReceived', function (val) { console.log('SACK: ' + (new Uint32Array([val]))[0]); });
}
catch(e)
{
}
console.log("Generating WebRTC Offer...");
signalingChannel.write({ cmd: "offer", data: peerConnection.generateOffer() });
}
function FOURBYTEBOUNDARY(a)
{
return ((a) + ((4 - ((a) % 4)) % 4));
}
function crc32c(crc, bytes)
{
var POLY = 0x82f63b78;
var n;
crc ^= 0xffffffff;
for (n = 0; n < bytes.length; n++) {
crc ^= bytes[n];
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
}
return crc ^ 0xffffffff;
}
function DebugPacket(val)
{
console.log('BufferLen: ' + val.length);
console.log('CRC32C: ' + val.readInt32LE(8))
val.writeUInt32BE(0, 8);
console.log('CRC32C/Calc: ' + crc32c(0, val));
console.log('VTAG: ' + val.readUInt32LE(4));
var ptr = 12;
while (ptr + 4 <= val.length)
{
var hdr = val.slice(ptr);
var chunkType = hdr[0];
var chunkFlags = hdr[1];
var chunkSize = hdr.readUInt16BE(2);
switch (chunkType) {
case 0:
console.log('DATA Chunk');
console.log('...chunkFlags: ' + chunkFlags);
console.log('...chunkLength: ' + chunkSize);
console.log('...TSN: ' + hdr.readUInt32BE(4));
console.log('...StreamID: ' + hdr.readUInt16BE(8));
console.log('...Seq: ' + hdr.readUInt16BE(10));
console.log('...ProtocolID: ' + hdr.readUInt32BE(12));
break;
default:
console.log('UNKNOWN Chunk');
console.log('...chunkFlags: ' + chunkFlags);
console.log('...chunkLength: ' + chunkSize);
break;
}
ptr += FOURBYTEBOUNDARY(chunkSize);
}
}
function OnSignalData(chunk)
{
var j = JSON.parse(chunk);
if (j.cmd == 'offer')
{
console.log("Received Offer");
signalingChannel.write({ cmd: "offer", data: peerConnection.setOffer(j.data) });
//signalingChannel.write({ cmd: "offer", data: peerConnection.setOffer(j.data) });
peerConnection.setOffer(j.data);
}
}
function OnLocalWebRequest(request, response)
@@ -66,24 +183,30 @@ function OnLocalWebRequest(request, response)
function OnWebRTC_Connected()
{
console.log("WebRTC Session Established");
//this.dc = this.createDataChannel("testChannel", OnTestChannel);
//if(mesh != null)
//{
// // Let create a data channel
// this.dc = this.createDataChannel("remoteDesktop", OnKVMChannel)
// this.tempTimeout = setTimeout(function (dc) { console.log("sending: 'test'"); dc.write("test"); }, 10000, this.dc);
//}
this.jsdc = this.createDataChannel("testChannel", OnTestChannel);
}
function OnTestChannel()
{
console.log("Successfully established Data Channel");
console.log("Successfully established JavaScript Data Channel");
if (mesh == null) {
RS.pipe(this);
}
else {
kvmStream = mesh.getRemoteDesktopStream();
kvmStream.pipe(this);
}
}
function OnKVMChannel()
{
console.log("Successfully established Data Channel to test Data throughput");
dc = this;
dc.kvm = mesh.getRemoteDesktopStream();
dc.on('data', function (buffer) { console.log("Peer Received: " + buffer.toString() + " bytes"); });
dc.on('data', function (buffer)
{
console.log("Peer Received: " + buffer.toString() + " bytes");
});
dc.on('end', function () { this.kvm.end(); console.log("Closing KVM Session"); });
dc.kvm.pipe(dc);
}
@@ -91,8 +214,21 @@ function OnWebRTC_DataChannel(dataChannel)
{
console.log("Data Channel (" + dataChannel.name + ") was created");
dc = dataChannel;
dc.on('data', function (buffer) { console.log("Received: " + buffer.length + " bytes"); dc.write(buffer.length.toString()); });
dc.on('data', function (buffer)
{
//console.log("Received: " + buffer);
});
dc.on('end', function () { console.log("Data Channel: " + this.name + " was closed"); });
//if (mesh == null)
//{
// RS.pipe(dc);
//}
//else
//{
// kvmStream = mesh.getRemoteDesktopStream();
// kvmStream.pipe(dc);
//}
}
function OnTunnelData(buffer)
{

View File

@@ -2,10 +2,11 @@ var http = require('http');
var https = require('https');
var WS;
console.log("Starting HTTP (Rewrite) Test");
console.displayStreamPipeMessages = 1;
console.displayFinalizerMessages = 1;
var cert = https.generateCertificate('test');
var server = https.createServer();
var cert = require('tls').generateCertificate('test');
var server = https.createServer({ pfx: cert, passphrase: 'test' });
server.on('request', function (imsg, rsp)
{
@@ -16,27 +17,28 @@ server.on('upgrade', function (imsg, sck, head)
{
console.log('Server On Upgrade');
WS = sck.upgradeWebSocket();
WS.on('pong', function () { console.log('Server received PONG'); WS.write('this is test'); WS.write(Buffer.from("This is a good day")); WS.end();});
WS.on('pong', function () { console.log('Server received PONG'); WS.write('this is test'); WS.write(Buffer.from("This is a good day.. Bye!")); WS.end();});
WS.on('data', function (chunk) { console.log('Server received: ' + chunk); });
WS.on('end', function () { console.log('Server WS ended'); WS = null; });
WS.ping();
});
server.listen({ port: 9095, pfx: cert, passphrase: 'test' });
server.listen({ port: 9095 });
//var req = http.get("http://127.0.0.1:9095/test.html");
//var req = http.get("ws://127.0.0.1:9095/test.html");
var req = http.request({ protocol: 'wss:', host: '127.0.0.1', port: 9095, method: 'GET', path: '/test.html', rejectUnauthorized: false})
req.end();
var req2 = http.request({ protocol: 'https:', host: '127.0.0.1', port: 9095, method: 'GET', path: '/test.html', rejectUnauthorized: false })
req2.end();
//var req2 = http.request({ protocol: 'https:', host: '127.0.0.1', port: 9095, method: 'GET', path: '/test.html', rejectUnauthorized: false })
//req2.end();
req.on('upgrade', function (imsg, sck, head)
{
console.log('client upgraded to WebSocket');
sck.on('ping', function () { console.log('Client received ping'); this.write('Client says hello');});
sck.on('data', function (chunk) { console.log('client received: ' + chunk, typeof (chunk)); });
sck.on('end', function () { console.log('Client side closed'); });
sck.on('end', function () { console.log('Client side closed'); console.logReferenceCount(req); req = null; _debugGC(); });
});
req.on('response', function (imsg)
{
@@ -47,10 +49,10 @@ req.on('response', function (imsg)
})
req.on('error', function (err) { console.log('error received', err); });
req2.on('response', function (imsg) {
console.log('received response', imsg.statusCode, imsg.statusMessage);
imsg.on('end', function () {
console.log('Done reading IncomingMessageStream');
});
})
req2.on('error', function (err) { console.log('error received', err); });
//req2.on('response', function (imsg) {
// console.log('received response', imsg.statusCode, imsg.statusMessage);
// imsg.on('end', function () {
// console.log('Done reading IncomingMessageStream');
// });
//})
//req2.on('error', function (err) { console.log('error received', err); });

View File

@@ -32,7 +32,7 @@
SOURCES = microstack/ILibAsyncServerSocket.c microstack/ILibAsyncSocket.c microstack/ILibAsyncUDPSocket.c microstack/ILibParsers.c microstack/ILibMulticastSocket.c
SOURCES += microstack/ILibRemoteLogging.c microstack/ILibWebClient.c microstack/ILibWebRTC.c microstack/ILibWebServer.c microstack/ILibCrypto.c
SOURCES += microstack/ILibWrapperWebRTC.c microstack/md5.c microstack/sha1.c microstack/ILibSimpleDataStore.c microstack/ILibProcessPipe.c microstack/ILibIPAddressMonitor.c
SOURCES += microscript/duktape.c microscript/ILibAsyncSocket_Duktape.c microscript/ILibDuktape_DuplexStream.c microscript/ILibDuktape_Helpers.c
SOURCES += microscript/duktape.c microscript/duk_module_duktape.c microscript/ILibAsyncSocket_Duktape.c microscript/ILibDuktape_DuplexStream.c microscript/ILibDuktape_Helpers.c
SOURCES += microscript/ILibDuktape_http.c microscript/ILibDuktape_net.c microscript/ILibDuktape_ReadableStream.c microscript/ILibDuktape_WritableStream.c
SOURCES += microscript/ILibDuktapeModSearch.c microscript/ILibParsers_Duktape.c microscript/ILibWebClient_Duktape.c microscript/ILibDuktape_WebRTC.c
SOURCES += microscript/ILibWebServer_Duktape.c microscript/ILibDuktape_SimpleDataStore.c microscript/ILibDuktape_GenericMarshal.c
@@ -188,6 +188,11 @@ else
CFLAGS += -D_NOHECI
endif
ifeq ($(WEBRTCDEBUG),1)
# Adds WebRTC Debug Interfaces
CFLAGS += -D_WEBRTCDEBUG
endif
ifneq ($(WatchDog),)
CWATCHDOG := -DILibChain_WATCHDOG_TIMEOUT=$(WatchDog)
endif
@@ -264,7 +269,7 @@ $(LIBNAME): $(OBJECTS) $(SOURCES)
# Compile on Raspberry Pi 2/3 with KVM
pi:
$(MAKE) EXENAME="meshagent_pi" CFLAGS="-std=gnu99 -g -Wall -D_POSIX -DMICROSTACK_PROXY -D_LINKVM $(CWEBLOG) $(CWATCHDOG) -fno-strict-aliasing $(INCDIRS) -DMESH_AGENTID=25 -D_NOFSWATCHER -D_NOHECI" LDFLAGS="-Lopenssl/libstatic/linux/pi $(LDFLAGS) $(LDEXTRA)"
$(MAKE) EXENAME="meshagent_pi" CFLAGS="-std=gnu99 -g -Wall -D_POSIX -DMICROSTACK_PROXY -DMICROSTACK_TLS_DETECT -D_LINKVM $(CWEBLOG) $(CWATCHDOG) -fno-strict-aliasing $(INCDIRS) -DMESH_AGENTID=25 -D_NOFSWATCHER -D_NOHECI" LDFLAGS="-Lopenssl/libstatic/linux/pi $(LDFLAGS) $(LDEXTRA)"
strip meshagent_pi
linux:

View File

@@ -25,9 +25,9 @@
<ClCompile Include="..\meshcore\KVM\Windows\tile.cpp" />
<ClCompile Include="..\meshcore\meshinfo.c" />
<ClCompile Include="..\microscript\duktape.c" />
<ClCompile Include="..\microscript\duk_module_duktape.c" />
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c" />
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c" />
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c" />
<ClCompile Include="..\microscript\ILibDuktape_Dgram.c" />
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" />
<ClCompile Include="..\microscript\ILibDuktape_EncryptionStream.c" />
@@ -48,9 +48,6 @@
<ClCompile Include="..\microscript\ILibDuktape_SimpleDataStore.c" />
<ClCompile Include="..\microscript\ILibDuktape_WebRTC.c" />
<ClCompile Include="..\microscript\ILibDuktape_WritableStream.c" />
<ClCompile Include="..\microscript\ILibParsers_Duktape.c" />
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c" />
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c" />
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c" />
<ClCompile Include="..\microstack\ILibAsyncSocket.c" />
<ClCompile Include="..\microstack\ILibAsyncUDPSocket.c" />
@@ -76,9 +73,9 @@
<ClInclude Include="..\meshcore\meshinfo.h" />
<ClInclude Include="..\microscript\duktape.h" />
<ClInclude Include="..\microscript\duk_config.h" />
<ClInclude Include="..\microscript\duk_module_duktape.h" />
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h" />
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h" />
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h" />
<ClInclude Include="..\microscript\ILibDuktape_Dgram.h" />
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" />
<ClInclude Include="..\microscript\ILibDuktape_EncryptionStream.h" />
@@ -97,9 +94,6 @@
<ClInclude Include="..\microscript\ILibDuktape_SimpleDataStore.h" />
<ClInclude Include="..\microscript\ILibDuktape_WebRTC.h" />
<ClInclude Include="..\microscript\ILibDuktape_WritableStream.h" />
<ClInclude Include="..\microscript\ILibParsers_Duktape.h" />
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h" />
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h" />
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h" />
<ClInclude Include="..\microstack\ILibAsyncSocket.h" />
<ClInclude Include="..\microstack\ILibAsyncUDPSocket.h" />
@@ -189,7 +183,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>MESH_AGENTID=1;NOLMSCOMMANDER;_DEBUG;MICROSTACK_PROXY;_LINKVM;DUK_OPT_DEBUGGER_SUPPORT;DUK_OPT_INTERRUPT_COUNTER;WIN32;WINSOCK2;_WINSOCK_DEPRECATED_NO_WARNINGS;_MSC_PLATFORM_TOOLSET_$(PlatformToolset);MICROSTACK_TLS_DETECT;MICROSTACK_NO_STDAFX;_REMOTELOGGING;_REMOTELOGGINGSERVER;ILibChain_WATCHDOG_TIMEOUT=600000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MESH_AGENTID=1;NOLMSCOMMANDER;_DEBUG;MICROSTACK_PROXY;_LINKVM;WIN32;WINSOCK2;_WINSOCK_DEPRECATED_NO_WARNINGS;_MSC_PLATFORM_TOOLSET_$(PlatformToolset);MICROSTACK_TLS_DETECT;MICROSTACK_NO_STDAFX;_REMOTELOGGING;_REMOTELOGGINGSERVER;ILibChain_WATCHDOG_TIMEOUT=600000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\openssl\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ExceptionHandling>Async</ExceptionHandling>
@@ -214,6 +208,9 @@
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
<PostBuildEvent>
<Command>"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -244,6 +241,9 @@
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -21,9 +21,6 @@
<ClInclude Include="..\microscript\duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h">
<Filter>Microscript</Filter>
</ClInclude>
@@ -51,15 +48,6 @@
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibParsers_Duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h">
<Filter>Microstack</Filter>
</ClInclude>
@@ -154,14 +142,14 @@
<ClInclude Include="..\microscript\ILibDuktape_HECI.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\duk_module_duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\microscript\duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c">
<Filter>Microscript</Filter>
</ClCompile>
@@ -189,15 +177,6 @@
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibParsers_Duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c">
<Filter>Microstack</Filter>
</ClCompile>
@@ -295,6 +274,9 @@
<ClCompile Include="..\microscript\ILibDuktape_HttpStream.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\duk_module_duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="MeshConsole.rc" />

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ limitations under the License.
#endif
#include "microscript/ILibDuktape_ScriptContainer.h"
#include "microstack/ILibCrypto.h"
MeshAgentHostContainer *agentHost = NULL;

View File

@@ -224,7 +224,7 @@ void getAvailableDisplays(unsigned short **array, int *len) {
if (dir != NULL) {
*len = scandir("/tmp/", &ent, lockfileCheckFn, alphasort);
if ((*array = (unsigned short *)malloc(*len)) == NULL) ILIBCRITICALEXIT(254);
if ((*array = (unsigned short *)malloc((*len)*sizeof(unsigned short))) == NULL) ILIBCRITICALEXIT(254);
for (i = 0; i < *len; i++) {
int dispNo = 0;

View File

@@ -390,7 +390,7 @@ int getScreenBuffer(char **desktop, long long *desktopsize, XImage *image)
if (*desktopsize != size) {
if (*desktop != NULL) { free(*desktop); }
*desktopsize = size;
if ((*desktop = (char *) malloc (*desktopsize)) == NULL) ILIBCRITICALEXIT(254);
if ((*desktop = (char *) malloc (*desktopsize + 4)) == NULL) ILIBCRITICALEXIT(254);
}
if (bpp == 16) {

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2015 Intel Corporation
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2015 Intel Corporation
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2015 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -111,6 +111,7 @@ int kvm_relay_restart(int paused, void *pipeMgr, char *exePath, ILibKVM_WriteHan
HANDLE hStdOut = INVALID_HANDLE_VALUE;
HANDLE hStdIn = INVALID_HANDLE_VALUE;
int ThreadRunning = 0;
int kvmConsoleMode = 0;
ILibRemoteLogging gKVMRemoteLogging = NULL;
#ifdef _WINSERVICE
@@ -379,7 +380,7 @@ void CheckDesktopSwitch(int checkres, ILibKVM_WriteHandler writeHandler, void *r
if (SCREEN_X != x || SCREEN_Y != y || SCREEN_WIDTH != w || SCREEN_HEIGHT != h || SCALING_FACTOR != SCALING_FACTOR_NEW)
{
printf("RESOLUTION CHANGED! (supposedly)\n");
//printf("RESOLUTION CHANGED! (supposedly)\n");
SCREEN_X = x;
SCREEN_Y = y;
SCREEN_WIDTH = w;
@@ -460,12 +461,13 @@ int kvm_server_inputdata(char* block, int blocklen, ILibKVM_WriteHandler writeHa
{
unsigned short type, size;
// Decode the block header
if (blocklen < 4) return 0;
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM [SLAVE]: Handle Input [Len = %d]", blocklen);
// KVMDEBUG("kvm_server_inputdata", blocklen);
CheckDesktopSwitch(0, writeHandler, reserved);
// Decode the block header
if (blocklen < 4) return 0;
type = ntohs(((unsigned short*)(block))[0]);
size = ntohs(((unsigned short*)(block))[1]);
@@ -649,22 +651,25 @@ typedef struct kvm_data_handler
// This method consumes as many input commands as it can.
int kvm_relay_feeddata(char* buf, int len, ILibKVM_WriteHandler writeHandler, void *reserved)
{
#ifdef _WINSERVICE
if (len >= 2 && ntohs(((unsigned short*)buf)[0]) == MNG_CTRLALTDEL)
if (gChildProcess != NULL)
{
HANDLE ht = CreateThread(NULL, 0, kvm_ctrlaltdel, 0, 0, 0);
if (ht != NULL) CloseHandle(ht);
if (len >= 2 && ntohs(((unsigned short*)buf)[0]) == MNG_CTRLALTDEL)
{
HANDLE ht = CreateThread(NULL, 0, kvm_ctrlaltdel, 0, 0, 0);
if (ht != NULL) CloseHandle(ht);
}
ILibProcessPipe_Process_WriteStdIn(gChildProcess, buf, len, ILibTransport_MemoryOwnership_USER);
ILibRemoteLogging_printf(ILibChainGetLogger(gILibChain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM [Master]: Write Input [Type = %u]", ntohs(((unsigned short*)buf)[0]));
return len;
}
else
{
int len2 = 0;
int ptr = 0;
//while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, kvm_relay_feeddata_ex, (void*[]) {writeHandler, reserved})) != 0) { ptr += len2; }
while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, writeHandler, reserved)) != 0) { ptr += len2; }
return ptr;
}
ILibProcessPipe_Process_WriteStdIn(gChildProcess, buf, len, ILibTransport_MemoryOwnership_USER);
ILibRemoteLogging_printf(ILibChainGetLogger(gILibChain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM [Master]: Write Input [Type = %u]", ntohs(((unsigned short*)buf)[0]));
return len;
#else
int len2 = 0;
int ptr = 0;
//while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, kvm_relay_feeddata_ex, (void*[]) {writeHandler, reserved})) != 0) { ptr += len2; }
while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, writeHandler, reserved)) != 0) { ptr += len2; }
return ptr;
#endif
}
// Set the KVM pause state
@@ -781,9 +786,12 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
void *reserved = ((void**)parm)[1];
#ifdef _WINSERVICE
gKVMRemoteLogging = ILibRemoteLogging_Create(NULL);
ILibRemoteLogging_SetRawForward(gKVMRemoteLogging, sizeof(KVMDebugLog), kvm_slave_OnRawForwardLog);
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: Child Processing Running...");
if (!kvmConsoleMode)
{
gKVMRemoteLogging = ILibRemoteLogging_Create(NULL);
ILibRemoteLogging_SetRawForward(gKVMRemoteLogging, sizeof(KVMDebugLog), kvm_slave_OnRawForwardLog);
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: Child Processing Running...");
}
#endif
// This basic lock will prevent 2 thread from running at the same time. Gives time for the first one to fully exit.
@@ -798,27 +806,39 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
KVMDEBUG("kvm_server_mainloop / start1", (int)GetCurrentThreadId());
#ifdef _WINSERVICE
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (!kvmConsoleMode)
{
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
}
#endif
KVMDEBUG("kvm_server_mainloop / start2", (int)GetCurrentThreadId());
if (!initialize_gdiplus())
{
if (!initialize_gdiplus())
{
#ifdef _WINSERVICE
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() failed");
if (!kvmConsoleMode)
{
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() failed");
}
#endif
KVMDEBUG("kvm_server_mainloop / initialize_gdiplus failed", (int)GetCurrentThreadId()); return 0;
KVMDEBUG("kvm_server_mainloop / initialize_gdiplus failed", (int)GetCurrentThreadId()); return 0;
}
#ifdef _WINSERVICE
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() SUCCESS");
if (!kvmConsoleMode)
{
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() SUCCESS");
}
#endif
kvm_server_SetResolution(writeHandler, reserved);
#ifdef _WINSERVICE
g_shutdown = 0;
kvmthread = CreateThread(NULL, 0, kvm_mainloopinput, parm, 0, 0);
if (!kvmConsoleMode)
{
g_shutdown = 0;
kvmthread = CreateThread(NULL, 0, kvm_mainloopinput, parm, 0, 0);
}
#endif
// Set all CRCs to 0xFF
@@ -864,7 +884,10 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
if (get_desktop_buffer(&desktop, &desktopsize) == 1)
{
#ifdef _WINSERVICE
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: get_desktop_buffer() failed");
if (!kvmConsoleMode)
{
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: get_desktop_buffer() failed");
}
#endif
KVMDEBUG("get_desktop_buffer() failed, shutting down", (int)GetCurrentThreadId());
g_shutdown = 1;
@@ -979,32 +1002,22 @@ void kvm_relay_ExitHandler(ILibProcessPipe_Process sender, int exitCode, void* u
void kvm_relay_StdOutHandler(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
{
int ptr = 0;
unsigned short size = 0;
unsigned short cmd = 0;
UNREFERENCED_PARAMETER(sender);
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)user)[0];
void *reserved = ((void**)user)[1];
while (bufferLen - ptr > 4)
if (bufferLen > 4)
{
//type = ntohs(((unsigned short*)(pchRequest + ptr))[0]);
size = ntohs(((unsigned short*)(buffer + ptr))[1]);
cmd = ntohs(((unsigned short*)(buffer + ptr))[0]);
if ((ptr + size > bufferLen) || size == 0) break;
ptr += size;
}
if (ptr > 0)
{
//ILibRemoteLogging_printf(ILibChainGetLogger(gILibChain), ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM Data: CMD: %d, Size = %d", cmd, size);
writeHandler(buffer, ptr, reserved); // stream object will take care of flow control
*bytesConsumed = ptr;
}
else
{
*bytesConsumed = 0;
size = ntohs(((unsigned short*)(buffer))[1]);
if (size <= bufferLen)
{
*bytesConsumed = size;
writeHandler(buffer, size, reserved);
return;
}
}
*bytesConsumed = 0;
}
void kvm_relay_StdErrHandler(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
{
@@ -1055,24 +1068,31 @@ int kvm_relay_restart(int paused, void *pipeMgr, char *exePath, ILibKVM_WriteHan
// Setup the KVM session. Return 1 if ok, 0 if it could not be setup.
int kvm_relay_setup(char *exePath, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved)
{
if (processPipeMgr != NULL)
{
#ifdef _WINSERVICE
// if (kvmthread != NULL || g_slavekvm != 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); return 0; }
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); return 0; }
g_restartcount = 0;
gProcessSpawnType = ILibProcessPipe_SpawnTypes_USER;
KVMDEBUG("kvm_relay_setup() session starting", 0);
return kvm_relay_restart(1, processPipeMgr, exePath, writeHandler, reserved);
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); return 0; }
g_restartcount = 0;
gProcessSpawnType = ILibProcessPipe_SpawnTypes_USER;
KVMDEBUG("kvm_relay_setup() session starting", 0);
return kvm_relay_restart(1, processPipeMgr, exePath, writeHandler, reserved);
#else
// if (kvmthread != NULL && g_shutdown == 0) return 0;
void **parms = (void**)ILibMemory_Allocate((2 * sizeof(void*)) + sizeof(int), 0, NULL, NULL);
parms[0] = writeHandler;
parms[1] = reserved;
((int*)(&parms[2]))[0] = 1;
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); free(parms); return 0; }
kvmthread = CreateThread(NULL, 0, kvm_server_mainloop, (void*)parms, 0, 0);
return 1;
return(0);
#endif
}
else
{
// if (kvmthread != NULL && g_shutdown == 0) return 0;
void **parms = (void**)ILibMemory_Allocate((2 * sizeof(void*)) + sizeof(int), 0, NULL, NULL);
parms[0] = writeHandler;
parms[1] = reserved;
((int*)(&parms[2]))[0] = 1;
kvmConsoleMode = 1;
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); free(parms); return 0; }
kvmthread = CreateThread(NULL, 0, kvm_server_mainloop, (void*)parms, 0, 0);
return 1;
}
}
// Force a KVM reset & refresh

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2015 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2015 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2015 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -68,12 +68,12 @@ limitations under the License.
#define MESH_MCASTv4_GROUP "239.255.255.235"
#define MESH_MCASTv6_GROUP "FF02:0:0:0:0:0:0:FE"
char exeMeshPolicyGuid[] = { 0xB9, 0x96, 0x01, 0x58, 0x80, 0x54, 0x4A, 0x19, 0xB7, 0xF7, 0xE9, 0xBE, 0x44, 0x91, 0x4C, 0x19 };
#define MESH_SCRIPTCONTAINER_ID "\xFF_ScriptContainer_ID"
#define MESH_AGENT_SINGLETON "\xFF_MeshAgentObject_Singleton"
#define SEQ_TABLE_KEY "\xFF_seqTable"
#define CONTAINER_PTR "\xFF_ptr"
#define MESH_AGENT_PTR "\xFFMeshAgentPtr"
#define MESH_AGENT_DUKPTRS "\xFFptrs"
#define CTX_PTR "\xFF_Heap"
#define CONTEXT_GUID_PTR "_CONTEXT_GUID_PTR"
#define REMOTE_DESKTOP_STREAM "\xFF_RemoteDesktopStream"
@@ -521,85 +521,28 @@ void IPAddressMonitor(void *data)
Begin Mesh Agent Duktape Abstraction
--------------------------------*/
MeshAgentDuktapePtrs* ILibDuktape_MeshAgent_GetMeshAgentPtrs(duk_context *ctx)
{
MeshAgentDuktapePtrs *ptrs = NULL;
MeshAgentHostContainer *agent = NULL;
duk_push_this(ctx); // [MeshAgent]
if (duk_has_prop_string(ctx, -1, MESH_AGENT_DUKPTRS))
{
// We already created a binding earlier
duk_get_prop_string(ctx, -1, MESH_AGENT_DUKPTRS); // [MeshAgent][ptrs]
ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx); // [MeshAgent]
}
else
{
// Create a new binding
duk_push_fixed_buffer(ctx, sizeof(MeshAgentDuktapePtrs)); // [MeshAgent][buffer]
ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, MESH_AGENT_DUKPTRS); // [MeshAgent]
memset(ptrs, 0, sizeof(MeshAgentDuktapePtrs));
ptrs->ctx = ctx;
ptrs->MeshAgentObject = duk_get_heapptr(ctx, -1);
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [MeshAgent][Host]
agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
duk_pop(ctx); // [MeshAgent]
ptrs->Next = agent->DuktapeMeshBindings;
agent->DuktapeMeshBindings = ptrs;
}
duk_pop(ctx); // ...
return ptrs;
}
duk_ret_t ILibDuktape_MeshAgent_AddCommandHandler(duk_context *ctx)
{
MeshAgentDuktapePtrs *ptrs;
void *OnCommand = duk_require_heapptr(ctx, 0);
ptrs = ILibDuktape_MeshAgent_GetMeshAgentPtrs(ctx);
ptrs->OnCommand = OnCommand;
duk_push_this(ctx); // [agent]
duk_get_prop_string(ctx, -1, "on"); // [agent][on]
duk_swap_top(ctx, -2); // [on][this]
duk_push_string(ctx, "Command"); // [on][this][Command]
duk_dup(ctx, 0); // [on][this][Command][listener]
duk_call_method(ctx, 2);
return 0;
}
duk_ret_t ILibDuktape_MeshAgent_AddConnectHandler(duk_context *ctx)
{
MeshAgentDuktapePtrs *ptrs;
void *OnConnect = duk_require_heapptr(ctx, 0);
ptrs = ILibDuktape_MeshAgent_GetMeshAgentPtrs(ctx);
ptrs->OnConnect = OnConnect;
duk_push_this(ctx); // [agent]
duk_get_prop_string(ctx, -1, "on"); // [agent][on]
duk_swap_top(ctx, -2); // [on][this]
duk_push_string(ctx, "Connected"); // [on][this][connected]
duk_dup(ctx, 0); // [on][this][connected][listener]
duk_call_method(ctx, 2);
return 0;
}
duk_ret_t ILibDuktape_MeshAgent_Finalizer(duk_context *ctx)
{
MeshAgentDuktapePtrs *ptrs = NULL, *binding = NULL;
MeshAgentHostContainer *agent = NULL;
duk_dup(ctx, 0); // [MeshAgent]
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [MeshAgent][MeshAgentPtr]
agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
if (duk_has_prop_string(ctx, -2, MESH_AGENT_DUKPTRS))
{
duk_get_prop_string(ctx, -2, MESH_AGENT_DUKPTRS); // [MeshAgent][MeshAgentPtr][ptrs]
ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
if (agent->DuktapeMeshBindings == ptrs)
{
agent->DuktapeMeshBindings = ptrs->Next;
}
else
{
binding = agent->DuktapeMeshBindings;
while (binding->Next != NULL)
{
if (binding->Next == ptrs) { binding->Next = ptrs->Next; break; }
binding = binding->Next;
}
}
}
return 0;
}
@@ -735,7 +678,6 @@ void ILibDuktape_MeshAgent_RemoteDesktop_EndSink(ILibDuktape_DuplexStream *strea
duk_push_heapptr(ptrs->ctx, ptrs->MeshAgentObject); // [MeshAgent]
duk_del_prop_string(ptrs->ctx, -1, REMOTE_DESKTOP_STREAM);
duk_pop(ptrs->ctx); // ...
memset(ptrs, 0, sizeof(RemoteDesktop_Ptrs));
}
kvm_cleanup();
@@ -745,7 +687,7 @@ void ILibDuktape_MeshAgent_RemoteDesktop_PauseSink(ILibDuktape_DuplexStream *sen
{
//printf("KVM/PAUSE\n");
#ifdef _POSIX
ILibProcessPipe_Pipe_Pause(((RemoteDesktop_Ptrs*)user)->kvmPipe);
if (((RemoteDesktop_Ptrs*)user)->kvmPipe != NULL) { ILibProcessPipe_Pipe_Pause(((RemoteDesktop_Ptrs*)user)->kvmPipe); }
#else
kvm_pause(1);
#endif
@@ -755,7 +697,7 @@ void ILibDuktape_MeshAgent_RemoteDesktop_ResumeSink(ILibDuktape_DuplexStream *se
//printf("KVM/RESUME\n");
#ifdef _POSIX
ILibProcessPipe_Pipe_Resume(((RemoteDesktop_Ptrs*)user)->kvmPipe);
if (((RemoteDesktop_Ptrs*)user)->kvmPipe != NULL) { ILibProcessPipe_Pipe_Resume(((RemoteDesktop_Ptrs*)user)->kvmPipe); }
#else
kvm_pause(0);
#endif
@@ -838,7 +780,11 @@ duk_ret_t ILibDuktape_MeshAgent_getRemoteDesktop(duk_context *ctx)
// Setup Remote Desktop
#ifdef WIN32
kvm_relay_setup(agent->exePath, agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
#ifdef _WINSERVICE
kvm_relay_setup(agent->exePath, agent->runningAsConsole ? NULL : agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
#else
kvm_relay_setup(agent->exePath, NULL, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
#endif
#else
ptrs->kvmPipe = kvm_relay_setup(agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
#endif
@@ -933,18 +879,55 @@ duk_ret_t ILibDuktape_MeshAgent_isControlChannelConnected(duk_context *ctx)
duk_ret_t ILibDuktape_MeshAgent_eval(duk_context *ctx)
{
duk_size_t evalStrLen;
char *evalStr = duk_get_lstring(ctx, 0, &evalStrLen);
char *evalStr = (char*)duk_get_lstring(ctx, 0, &evalStrLen);
printf("eval(): %s\n", evalStr);
duk_eval_string(ctx, evalStr);
return(1);
}
duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID);
void ILibDuktape_MeshAgent_dumpCoreModuleEx(void *chain, void *user)
{
MeshAgentHostContainer* agentHost = (MeshAgentHostContainer*)user;
char *CoreModule;
ScriptEngine_Stop((MeshAgentHostContainer*)user, MeshAgent_JavaCore_ContextGuid);
printf("CoreModule was manually dumped, restarting!\n");
int CoreModuleLen = ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0);
if (CoreModuleLen > 0)
{
// There is a core module, launch it now.
CoreModule = (char*)ILibMemory_Allocate(CoreModuleLen, 0, NULL, NULL);
ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", CoreModule, CoreModuleLen);
if (ILibDuktape_ScriptContainer_CompileJavaScript(agentHost->meshCoreCtx, CoreModule + 4, CoreModuleLen - 4) != 0 ||
ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
{
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint,
ILibRemoteLogging_Flags_VerbosityLevel_1, "Error Executing MeshCore: %s", duk_safe_to_string(agentHost->meshCoreCtx, -1));
duk_pop(agentHost->meshCoreCtx);
}
free(CoreModule);
}
agentHost->localScript = 1;
}
duk_ret_t ILibDuktape_MeshAgent_dumpCoreModule(duk_context *ctx)
{
duk_push_this(ctx); // [agent]
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [agent][ptr]
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
agent->localScript = 0;
ILibChain_RunOnMicrostackThreadEx(agent->chain, ILibDuktape_MeshAgent_dumpCoreModuleEx, agent);
return(0);
}
void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
{
MeshAgentHostContainer *agent;
ILibDuktape_EventEmitter *emitter;
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, MESH_AGENT_SINGLETON))
{
@@ -959,6 +942,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
duk_pop_2(ctx); // ...
duk_push_object(ctx); // [MeshAgent]
ILibDuktape_WriteID(ctx, "MeshAgent");
duk_push_pointer(ctx, agent); // [MeshAgent][ptr]
duk_put_prop_string(ctx, -2, MESH_AGENT_PTR); // [MeshAgent]
@@ -979,18 +963,10 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
duk_push_pointer(ctx, &agent->selfcert);
duk_put_prop_string(ctx, -2, ILibDuktape_MeshAgent_Cert_NonLeaf);
#endif
duk_push_fixed_buffer(ctx, sizeof(MeshAgentDuktapePtrs)); // [MeshAgent][buffer]
MeshAgentDuktapePtrs *ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, MESH_AGENT_DUKPTRS); // [MeshAgent]
memset(ptrs, 0, sizeof(MeshAgentDuktapePtrs));
ptrs->ctx = ctx;
ptrs->MeshAgentObject = duk_get_heapptr(ctx, -1);
ptrs->Next = agent->DuktapeMeshBindings;
agent->DuktapeMeshBindings = ptrs;
ILibDuktape_EventEmitter_CreateEvent(emitter, "Ready", &(ptrs->OnReady));
ILibDuktape_EventEmitter_CreateEvent(emitter, "Connected", &(ptrs->OnConnect));
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Ready");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Connected");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Command");
ILibDuktape_CreateEventWithGetter(ctx, "isControlChannelConnected", ILibDuktape_MeshAgent_isControlChannelConnected);
ILibDuktape_EventEmitter_AddHook(emitter, "Ready", ILibDuktape_MeshAgent_Ready);
@@ -1002,6 +978,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "SendCommand", ILibDuktape_MeshAgent_SendCommand, 1);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_MeshAgent_Finalizer);
ILibDuktape_CreateReadonlyProperty_int(ctx, "activeMicroLMS", (agent->microLMS != NULL ? 1 : 0));
ILibDuktape_CreateInstanceMethod(ctx, "restartCore", ILibDuktape_MeshAgent_dumpCoreModule, 0);
#ifdef _LINKVM
ILibDuktape_CreateReadonlyProperty_int(ctx, "hasKVM", 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "kvmConnected");
@@ -1264,7 +1241,7 @@ duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID)
ILibDuktape_MeshAgent_Init(newCtx, agent->chain, agent);
ILibDuktape_SetNativeUncaughtExceptionHandler(newCtx, settings->nExeptionHandler, settings->nExceptionUserObject);
if (g_displayFinalizerMessages) { printf("\n\n==> Stopping JavaScript Engine\n"); }
duk_destroy_heap(oldCtx);
agent->meshCoreCtx = newCtx;
if (agent->proxyServer != NULL)
@@ -1314,10 +1291,131 @@ void MeshServer_OnSendOK(ILibWebClient_StateObject sender, void *user1, void *us
// TODO: Inform JavaScript core module that we are in underflow situation
}
int GenerateSHA384FileHash(char *filePath, char *fileHash)
{
FILE *tmpFile = NULL;
unsigned int endIndex = 0;
unsigned int bytesLeft = 0;
size_t bytesRead;
unsigned int checkSumIndex = 0;
unsigned int tableIndex = 0;
#ifdef WIN32
int retVal = 1;
fopen_s(&tmpFile, filePath, "rb");
#else
tmpFile = fopen(filePath, "rb");
#endif
if (tmpFile == NULL) { return(1); }
#ifdef WIN32
// We need to check if this is a signed binary
// Read the PE Headers, to determine where to look for the Embedded JS
char *optHeader = NULL;
unsigned int NTHeaderIndex = 0;
fseek(tmpFile, 0, SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 2, tmpFile));
if (ntohs(((unsigned int*)ILibScratchPad)[0]) == 19802) // 5A4D
{
fseek(tmpFile, 60, SEEK_SET);
ignore_result(fread((void*)&NTHeaderIndex, 1, 4, tmpFile));
fseek(tmpFile, NTHeaderIndex, SEEK_SET); // NT HEADER
checkSumIndex = NTHeaderIndex + 24 + 64;
ignore_result(fread(ILibScratchPad, 1, 24, tmpFile));
if (((unsigned int*)ILibScratchPad)[0] == 17744)
{
// PE Image
optHeader = ILibMemory_AllocateA(((unsigned short*)ILibScratchPad)[10]);
ignore_result(fread(optHeader, 1, ILibMemory_AllocateA_Size(optHeader), tmpFile));
switch (((unsigned short*)optHeader)[0])
{
case 0x10B:
if (((unsigned int*)(optHeader + 128))[0] != 0)
{
endIndex = ((unsigned int*)(optHeader + 128))[0];
}
tableIndex = NTHeaderIndex + 24 + 128;
retVal = 0;
break;
case 0x20B:
if (((unsigned int*)(optHeader + 144))[0] != 0)
{
endIndex = ((unsigned int*)(optHeader + 144))[0];
}
tableIndex = NTHeaderIndex + 24 + 144;
retVal = 0;
break;
default:
break;
}
}
}
if (retVal != 0)
{
fclose(tmpFile);
return(1);
}
#endif
if (endIndex == 0)
{
// We just need to check for Embedded MSH file
int mshLen = 0;
fseek(tmpFile, -16, SEEK_END);
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
if (memcmp(ILibScratchPad, exeMeshPolicyGuid, 16) == 0)
{
fseek(tmpFile, -20, SEEK_CUR);
ignore_result(fread((void*)&mshLen, 1, 4, tmpFile));
mshLen = ntohl(mshLen);
endIndex = (unsigned int)ftell(tmpFile) - 4 - mshLen;
}
else
{
endIndex = (unsigned int)ftell(tmpFile);
}
}
SHA512_CTX ctx;
SHA384_Init(&ctx);
bytesLeft = endIndex;
fseek(tmpFile, 0, SEEK_SET);
if (checkSumIndex != 0)
{
bytesRead = fread(ILibScratchPad, 1, checkSumIndex + 4, tmpFile);
((unsigned int*)(ILibScratchPad + checkSumIndex))[0] = 0;
SHA384_Update(&ctx, ILibScratchPad, bytesRead);
if (endIndex > 0) { bytesLeft -= (unsigned int)bytesRead; }
bytesRead = fread(ILibScratchPad, 1, tableIndex + 8 - (checkSumIndex + 4), tmpFile);
((unsigned int*)(ILibScratchPad + bytesRead - 8))[0] = 0;
((unsigned int*)(ILibScratchPad + bytesRead - 8))[1] = 0;
SHA384_Update(&ctx, ILibScratchPad, bytesRead);
if (endIndex > 0) { bytesLeft -= (unsigned int)bytesRead; }
}
while ((bytesRead = fread(ILibScratchPad, 1, endIndex == 0 ? sizeof(ILibScratchPad) : (bytesLeft > sizeof(ILibScratchPad) ? sizeof(ILibScratchPad) : bytesLeft), tmpFile)) > 0)
{
SHA384_Update(&ctx, ILibScratchPad, bytesRead);
if (endIndex > 0)
{
bytesLeft -= (unsigned int)bytesRead;
if (bytesLeft == 0) { break; }
}
}
SHA384_Final((unsigned char*)fileHash, &ctx);
fclose(tmpFile);
return(0);
}
// Called when the connection of the mesh server is fully authenticated
void MeshServer_ServerAuthenticated(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent) {
int len = 0;
MeshAgentDuktapePtrs *meshBindings;
// Send the mesh agent tag to the server
// We send the tag information independently of the meshcore because we could use this to select what meshcore to use on the server.
@@ -1327,20 +1425,15 @@ void MeshServer_ServerAuthenticated(ILibWebClient_StateObject WebStateObject, Me
// Inform JavaScript core module of the connection
// TODO: Verify with Bryan that only the core module will get this. No other modules should.
if (agent->serverAuthState == 3) {
meshBindings = agent->DuktapeMeshBindings;
while (meshBindings != NULL)
{
if (meshBindings->OnConnect != NULL)
{
duk_push_heapptr(meshBindings->ctx, meshBindings->OnConnect);
duk_push_heapptr(meshBindings->ctx, meshBindings->MeshAgentObject);
duk_push_int(meshBindings->ctx, 1); // Argument 1 here indicates connection
if (duk_pcall_method(meshBindings->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(meshBindings->ctx); }
duk_pop(meshBindings->ctx);
}
meshBindings = meshBindings->Next;
}
if (agent->serverAuthState == 3)
{
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [agent]
duk_get_prop_string(agent->meshCoreCtx, -1, "emit"); // [agent][emit]
duk_swap_top(agent->meshCoreCtx, -2); // [emit][this]
duk_push_string(agent->meshCoreCtx, "Connected"); // [emit][this][Connected]
duk_push_int(agent->meshCoreCtx, 1); // [emit][this][Connected][1]
if (duk_pcall_method(agent->meshCoreCtx, 2) != 0) { ILibDuktape_Process_UncaughtException(agent->meshCoreCtx); }
duk_pop(agent->meshCoreCtx); // ...
}
}
@@ -1349,7 +1442,6 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
{
unsigned short command = ntohs(((unsigned short*)cmd)[0]);
unsigned short requestid;
MeshAgentDuktapePtrs *meshBindings;
#ifndef MICROSTACK_NOTLS
// If we are not authenticated with the mesh server, we only support auth commands.
@@ -1501,49 +1593,41 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
// TODO: Verify with Bryan that only the core module will get this. No other modules should.
if (cmd[0] == '{' || command >= 1000)
{
int processed = 0;
int popCount = 0;
// if (cmd[0] == '{') { cmd[cmdLen] = 0; printf("%s\r\n", cmd); } // DEBUG: Print JSON command
meshBindings = agent->DuktapeMeshBindings;
while (processed == 0 && meshBindings != NULL)
{
if (meshBindings->OnCommand != NULL)
{
duk_push_heapptr(meshBindings->ctx, meshBindings->OnCommand); // [func]
duk_push_heapptr(meshBindings->ctx, meshBindings->MeshAgentObject); // [func][this]
if (cmd[0] == '{')
{
// JSON
duk_push_global_object(meshBindings->ctx); // [g]
duk_get_prop_string(meshBindings->ctx, -1, "JSON"); // [g][JSON]
duk_get_prop_string(meshBindings->ctx, -1, "parse"); // [g][JSON][func]
duk_swap_top(meshBindings->ctx, -3); // [func][JSON][g]
duk_pop_2(meshBindings->ctx); // [func]
duk_push_lstring(meshBindings->ctx, cmd, cmdLen); // [func][str]
if (duk_pcall(meshBindings->ctx, 1) != 0)
{
duk_pop(meshBindings->ctx);
duk_push_lstring(meshBindings->ctx, cmd, cmdLen);
}
}
else
{
// BINARY
duk_push_external_buffer(meshBindings->ctx); // [func][this][buffer]
duk_config_buffer(meshBindings->ctx, -1, cmd, cmdLen);
}
if (duk_pcall_method(meshBindings->ctx, 1) == 0) // [retVal]
{
if (duk_is_number(meshBindings->ctx, -1)) { processed = duk_get_int(meshBindings->ctx, -1); } // Get the return value
}
else
{
ILibDuktape_Process_UncaughtException(meshBindings->ctx);
}
duk_pop(meshBindings->ctx); // ...
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [agent]
duk_get_prop_string(agent->meshCoreCtx, -1, "emit"); // [agent][emit]
duk_swap_top(agent->meshCoreCtx, -2); // [emit][this]
duk_push_string(agent->meshCoreCtx, "Command"); // [emit][this][Command]
if (cmd[0] == '{')
{
// JSON
duk_push_global_object(agent->meshCoreCtx); // [emit][this][Command][g]
duk_get_prop_string(agent->meshCoreCtx, -1, "JSON"); // [emit][this][Command][g][JSON]
duk_get_prop_string(agent->meshCoreCtx, -1, "parse"); // [emit][this][Command][g][JSON][func]
duk_swap_top(agent->meshCoreCtx, -3); // [emit][this][Command][func][JSON][g]
duk_pop_2(agent->meshCoreCtx); // [emit][this][Command][func]
duk_push_lstring(agent->meshCoreCtx, cmd, cmdLen); // [emit][this][Command][func][str]
if (duk_pcall(agent->meshCoreCtx, 1) != 0) // [emit][this][Command][JSON]
{
duk_pop(agent->meshCoreCtx); // [emit][this][Command]
duk_push_lstring(agent->meshCoreCtx, cmd, cmdLen); // [emit][this][Command][str]
}
meshBindings = meshBindings->Next;
popCount = 1;
}
else
{
// BINARY
duk_push_external_buffer(agent->meshCoreCtx); // [emit][this][Command][extBuffer]
duk_insert(agent->meshCoreCtx, -4); // [extBuffer][emit][this][Command]
duk_config_buffer(agent->meshCoreCtx, -4, cmd, cmdLen);
duk_push_buffer_object(agent->meshCoreCtx, -4, 0, cmdLen, DUK_BUFOBJ_NODEJS_BUFFER);// [extBuffer][emit][this][Command][buffer]
popCount = 2;
}
if (duk_pcall_method(agent->meshCoreCtx, 2) != 0) { ILibDuktape_Process_UncaughtException(agent->meshCoreCtx); }
duk_pop_n(agent->meshCoreCtx, popCount); // ...
return;
}
@@ -1685,16 +1769,19 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
{
// Indicates the end of the agent update transfer
// Check the SHA384 hash of the received file against the file we got.
if ((util_sha384file(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
if ((GenerateSHA384FileHash(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
{
printf("UPDATE: End OK\r\n");
// Check the file signature & version number
//if (signcheck_verifysign(updateFilePath, 1))
{
// Everything looks good, lets perform the update
agent->performSelfUpdate = 1;
ILibStopChain(agent->chain);
}
//printf("UPDATE: End OK\r\n");
#ifdef WIN32
agent->performSelfUpdate = 1;
#else
// Set performSelfUpdate to the startupType, on Linux is this important: 1 = systemd, 2 = upstart, 3 = sysv-init
int len = ILibSimpleDataStore_Get(agent->masterDb, "StartupType", ILibScratchPad, sizeof(ILibScratchPad));
if (len > 0) { agent->performSelfUpdate = atoi(ILibScratchPad); }
if (agent->performSelfUpdate == 0) { agent->performSelfUpdate = 999; } // Never allow this value to be zero.
#endif
// Everything looks good, lets perform the update
ILibStopChain(agent->chain);
} else {
// Hash check failed, delete the file and do nothing. On next server reconnect, we will try again.
util_deletefile(updateFilePath);
@@ -1816,18 +1903,15 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
if (agent->serverAuthState == 3)
#endif
{
MeshAgentDuktapePtrs *meshBindings = agent->DuktapeMeshBindings;
while (meshBindings != NULL)
if (agent->meshCoreCtx != NULL)
{
if (meshBindings->OnConnect != NULL)
{
duk_push_heapptr(meshBindings->ctx, meshBindings->OnConnect);
duk_push_heapptr(meshBindings->ctx, meshBindings->MeshAgentObject);
duk_push_int(meshBindings->ctx, 0); // 0 here as second parameter indicates disconnection
if (duk_pcall_method(meshBindings->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(meshBindings->ctx); }
duk_pop(meshBindings->ctx);
}
meshBindings = meshBindings->Next;
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [agent]
duk_get_prop_string(agent->meshCoreCtx, -1, "emit"); // [agent][emit]
duk_swap_top(agent->meshCoreCtx, -2); // [emit][this]
duk_push_string(agent->meshCoreCtx, "Connected"); // [emit][this][Connected]
duk_push_int(agent->meshCoreCtx, 0); // [emit][this][Connected][0] (0 means disconnected)
if (duk_pcall_method(agent->meshCoreCtx, 2) != 0) { ILibDuktape_Process_UncaughtException(agent->meshCoreCtx); }
duk_pop(agent->meshCoreCtx);
}
}
agent->controlChannel = NULL; // Set the agent MeshCentral server control channel
@@ -2094,7 +2178,50 @@ int ValidateMeshServer(ILibWebClient_RequestToken sender, int preverify_ok, STAC
}
#endif
void importSettings(MeshAgentHostContainer *agent, char* fileName)
void checkForEmbeddedMSH(MeshAgentHostContainer *agent)
{
FILE *tmpFile = NULL;
int mshLen;
#ifdef WIN32
fopen_s(&tmpFile, agent->exePath, "rb");
#else
tmpFile = fopen(agent->exePath, "rb");
#endif
if (tmpFile == NULL) { return; }
fseek(tmpFile, -16, SEEK_END);
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
if (memcmp(ILibScratchPad, exeMeshPolicyGuid, 16) == 0)
{
// Found Embedded MSH File
fseek(tmpFile, -20, SEEK_CUR);
if (fread((void*)&mshLen, 1, 4, tmpFile) == 4)
{
mshLen = ntohl(mshLen);
fseek(tmpFile, -4 - mshLen, SEEK_CUR);
char *eMSH = ILibMemory_AllocateA(mshLen);
if (fread(eMSH, 1, mshLen, tmpFile) == mshLen)
{
FILE *msh = NULL;
#ifdef WIN32
fopen_s(&msh, MeshAgent_MakeAbsolutePath(agent->exePath, ".msh"), "wb");
#else
msh = fopen(MeshAgent_MakeAbsolutePath(agent->exePath, ".msh"), "wb");
#endif
if (msh != NULL)
{
fwrite(eMSH, 1, mshLen, msh);
fclose(msh);
}
}
}
}
fclose(tmpFile);
}
int importSettings(MeshAgentHostContainer *agent, char* fileName)
{
int eq;
char* importFile;
@@ -2103,7 +2230,7 @@ void importSettings(MeshAgentHostContainer *agent, char* fileName)
parser_result_field *f;
importFileLen = ILibReadFileFromDiskEx(&importFile, fileName);
if (importFileLen == 0) { return; }
if (importFileLen == 0) { return(0); }
//printf("Importing settings file: %s\n", fileName);
pr = ILibParseString(importFile, 0, importFileLen, "\n", 1);
@@ -2152,6 +2279,8 @@ void importSettings(MeshAgentHostContainer *agent, char* fileName)
}
ILibDestructParserResults(pr);
free(importFile);
return(importFileLen);
}
void agentDumpKeysSink(ILibSimpleDataStore sender, char* Key, int KeyLen, void *user)
@@ -2207,7 +2336,12 @@ void MeshAgent_Slave(MeshAgentHostContainer *agentHost)
void MeshAgent_ChainEnd(void *chain, void *user)
{
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user;
if (agent->meshCoreCtx != NULL) { duk_destroy_heap(agent->meshCoreCtx); }
if (agent->meshCoreCtx != NULL)
{
if (g_displayFinalizerMessages) { printf("\n\n==> Stopping JavaScript Engine\n"); }
duk_destroy_heap(agent->meshCoreCtx);
}
agent->meshCoreCtx = NULL;
}
void MeshAgent_RunScriptOnly_Finalizer(duk_context *ctx, void *user)
@@ -2338,14 +2472,26 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
// Read the .proxy file if present and push it into the database
{
char* str = NULL;
int len = (int)util_readfile(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".proxy"), &str, 1024);
if (str != NULL) { ILibSimpleDataStore_PutEx(agentHost->masterDb, "WebProxy", 8, str, len); free(str); } else { ILibSimpleDataStore_DeleteEx(agentHost->masterDb, "WebProxy", 8); }
char tmp[255];
if (ILibSimpleDataStore_GetEx(agentHost->masterDb, "ignoreProxyFile", 15, tmp, sizeof(tmp)) == 0)
{
char* str = NULL;
int len = (int)util_readfile(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".proxy"), &str, 1024);
if (str != NULL) { ILibSimpleDataStore_PutEx(agentHost->masterDb, "WebProxy", 8, str, len); free(str); }
else { ILibSimpleDataStore_DeleteEx(agentHost->masterDb, "WebProxy", 8); }
}
}
// Check to see if we need to import a settings file
importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".mshx"));
importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh"));
if (importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".mshx")) == 0)
{
if (importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh")) == 0)
{
// Let's check to see if an .msh was embedded into our binary
checkForEmbeddedMSH(agentHost);
importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh"));
}
}
#ifdef WIN32
// If running as a Windows service, set basic values to the registry, this allows other applications to know what the mesh agent is doing.
@@ -2495,18 +2641,15 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
// Check if there is a CoreModule in the db
char *CoreModule;
int CoreModuleLen = agentHost->localScript == 0 ? ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0) : 0;
MeshAgentDuktapePtrs* ptrs = agentHost->DuktapeMeshBindings;
while (ptrs != NULL)
if (agentHost->meshCoreCtx != NULL)
{
if (ptrs->OnReady != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnReady); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->MeshAgentObject); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) {ILibDuktape_Process_UncaughtException(ptrs->ctx); } // [retVal]
duk_pop(ptrs->ctx); // ...
}
ptrs = ptrs->Next;
ILibDuktape_MeshAgent_PUSH(agentHost->meshCoreCtx, agentHost->chain); // [agent]
duk_get_prop_string(agentHost->meshCoreCtx, -1, "emit"); // [agent][emit]
duk_swap_top(agentHost->meshCoreCtx, -2); // [emit][this]
duk_push_string(agentHost->meshCoreCtx, "Ready"); // [emit][this][Ready]
if (duk_pcall_method(agentHost->meshCoreCtx, 1) != 0) { ILibDuktape_Process_UncaughtException(agentHost->meshCoreCtx); }
duk_pop(agentHost->meshCoreCtx); // ...
}
if (agentHost->localScript == 0)
@@ -2532,6 +2675,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
}
free(CoreModule);
if (ILibSimpleDataStore_Get(agentHost->masterDb, "noUpdateCoreModule", NULL, 0) != 0) { agentHost->localScript = 1; printf("** CoreModule: Update Disabled**\n"); }
}
}
@@ -2757,7 +2901,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
#endif
// Perform a self SHA384 Hash
util_sha384file(agentHost->exePath, agentHost->agentHash);
GenerateSHA384FileHash(agentHost->exePath, agentHost->agentHash);
#ifdef _REMOTELOGGINGSERVER
{
@@ -2812,8 +2956,8 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
ILibStartChain(agentHost->chain);
agentHost->chain = NULL; // Mesh agent has exited, set the chain to NULL
// Check if we need to perform self-update
if (agentHost->performSelfUpdate == 1)
// Check if we need to perform self-update (performSelfUpdate should indicate startup type on Liunx: 1 = systemd, 2 = upstart, 3 = sysv-init)
if (agentHost->performSelfUpdate != 0)
{
int i, ptr = 0;
#ifdef WIN32
@@ -2860,7 +3004,19 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
}
#else
// Linux version
{
if (agentHost->performSelfUpdate == 1) {
// Systemd is in use, move the update using "mv" and restart the systemd service
struct stat results;
stat(agentHost->exePath, &results); // This the mode of the current executable
chmod(updateFilePath, results.st_mode); // Set the new executable to the same mode as the current one.
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "mv \"%s\" \"%s\"", updateFilePath, agentHost->exePath); // Move the update over our own executable
if (system(ILibScratchPad)) {}
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "systemctl restart meshagent"); // Restart the service
if (system(ILibScratchPad)) {}
} else {
// Generic update process, call our own update with arguments.
struct stat results;
stat(agentHost->exePath, &results); // This the mode of the current executable
chmod(updateFilePath, results.st_mode); // Set the new executable to the same mode as the current one.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -118,16 +118,6 @@ typedef struct MeshAgent_Commands_SCRIPT_ExecuteString
}MeshAgent_Commands_SCRIPT_ExecuteString;
#pragma pack(pop)
typedef struct MeshAgentDuktapePtrs
{
struct MeshAgentDuktapePtrs *Next;
duk_context *ctx;
void *MeshAgentObject;
void *OnCommand;
void *OnConnect;
void *OnReady;
}MeshAgentDuktapePtrs;
typedef enum MeshAgentHost_BatteryInfo
{
MeshAgentHost_BatteryInfo_HIGH = 1,
@@ -148,7 +138,6 @@ typedef struct MeshAgentHostContainer
duk_context *meshCoreCtx;
char *meshCoreCtx_embeddedScript;
int meshCoreCtx_embeddedScriptLen;
MeshAgentDuktapePtrs *DuktapeMeshBindings;
ILibProcessPipe_Manager *pipeManager;
char* exePath;
@@ -192,6 +181,9 @@ typedef struct MeshAgentHostContainer
#ifndef WIN32
int dbRetryCount;
#endif
#if defined(_WINSERVICE)
int runningAsConsole;
#endif
}MeshAgentHostContainer;
MeshAgentHostContainer* MeshAgent_Create();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -95,10 +95,10 @@
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</PostBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
<TargetName>$(ProjectName)64</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -198,7 +198,8 @@
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"</Command>
<Command>REM signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"
"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
</PostBuildEvent>
<Manifest>
<AdditionalManifestFiles>$(ProjectDir)dpiaware.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
@@ -233,7 +234,8 @@
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"</Command>
<Command>REM signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"
"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
@@ -253,9 +255,9 @@
<ClCompile Include="..\meshcore\meshinfo.c" />
<ClCompile Include="..\meshcore\signcheck.c" />
<ClCompile Include="..\microscript\duktape.c" />
<ClCompile Include="..\microscript\duk_module_duktape.c" />
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c" />
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c" />
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c" />
<ClCompile Include="..\microscript\ILibDuktape_Dgram.c" />
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" />
<ClCompile Include="..\microscript\ILibDuktape_EncryptionStream.c" />
@@ -276,9 +278,6 @@
<ClCompile Include="..\microscript\ILibDuktape_SimpleDataStore.c" />
<ClCompile Include="..\microscript\ILibDuktape_WebRTC.c" />
<ClCompile Include="..\microscript\ILibDuktape_WritableStream.c" />
<ClCompile Include="..\microscript\ILibParsers_Duktape.c" />
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c" />
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c" />
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c" />
<ClCompile Include="..\microstack\ILibAsyncSocket.c" />
<ClCompile Include="..\microstack\ILibAsyncUDPSocket.c" />
@@ -306,9 +305,9 @@
<ClInclude Include="..\meshcore\signcheck.h" />
<ClInclude Include="..\microscript\duktape.h" />
<ClInclude Include="..\microscript\duk_config.h" />
<ClInclude Include="..\microscript\duk_module_duktape.h" />
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h" />
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h" />
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h" />
<ClInclude Include="..\microscript\ILibDuktape_Dgram.h" />
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" />
<ClInclude Include="..\microscript\ILibDuktape_EncryptionStream.h" />
@@ -327,9 +326,6 @@
<ClInclude Include="..\microscript\ILibDuktape_SimpleDataStore.h" />
<ClInclude Include="..\microscript\ILibDuktape_WebRTC.h" />
<ClInclude Include="..\microscript\ILibDuktape_WritableStream.h" />
<ClInclude Include="..\microscript\ILibParsers_Duktape.h" />
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h" />
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h" />
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h" />
<ClInclude Include="..\microstack\ILibAsyncSocket.h" />
<ClInclude Include="..\microstack\ILibAsyncUDPSocket.h" />

View File

@@ -34,9 +34,6 @@
<ClCompile Include="..\microscript\duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c">
<Filter>Microscript</Filter>
</ClCompile>
@@ -64,15 +61,6 @@
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibParsers_Duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c">
<Filter>Microstack</Filter>
</ClCompile>
@@ -172,6 +160,9 @@
<ClCompile Include="..\microscript\ILibDuktape_HttpStream.c">
<Filter>Microscript</Filter>
</ClCompile>
<ClCompile Include="..\microscript\duk_module_duktape.c">
<Filter>Microscript</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\microscript\duk_config.h">
@@ -180,9 +171,6 @@
<ClInclude Include="..\microscript\duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h">
<Filter>Microscript</Filter>
</ClInclude>
@@ -210,15 +198,6 @@
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibParsers_Duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h">
<Filter>Microstack</Filter>
</ClInclude>
@@ -316,5 +295,8 @@
<ClInclude Include="..\microscript\ILibDuktape_HECI.h">
<Filter>Microscript</Filter>
</ClInclude>
<ClInclude Include="..\microscript\duk_module_duktape.h">
<Filter>Microscript</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -226,11 +226,11 @@ BOOL InstallService()
// Update the faliure action
failactions[0].Type = SC_ACTION_RESTART;
failactions[0].Delay = 120000; // Wait 2 minutes before faliure restart (milliseconds)
failactions[0].Delay = 60000; // Wait 1 minutes before faliure restart (milliseconds)
failactions[1].Type = SC_ACTION_RESTART;
failactions[1].Delay = 120000; // Wait 2 minutes before faliure restart (milliseconds)
failactions[2].Type = SC_ACTION_NONE;
failactions[2].Delay = 120000;
failactions[1].Delay = 60000; // Wait 1 minutes before faliure restart (milliseconds)
failactions[2].Type = SC_ACTION_RESTART;
failactions[2].Delay = 60000;
memset(&fa, 0, sizeof(SERVICE_FAILURE_ACTIONS));
fa.dwResetPeriod = 86400; // After 1 days, reset the faliure counters (seconds)
fa.cActions = 3;
@@ -501,6 +501,14 @@ void fullinstall(int uninstallonly, char* proxy, int proxylen, char* tag, int ta
setup2[setup2len] = 0;
remove(setup2);
// Remove "[Executable].mshx" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "mshx", 5);
setup2[setup2len + 1] = 0;
remove(setup2);
// Remove "[Executable].proxy" file
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 257) return;
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
@@ -778,6 +786,7 @@ int main(int argc, char* argv[])
agent = MeshAgent_Create();
agent->meshCoreCtx_embeddedScript = integratedJavaScript;
agent->meshCoreCtx_embeddedScriptLen = integragedJavaScriptLen;
if (integratedJavaScript != NULL || (argc > 1 && strcasecmp(argv[1], "run") == 0)) { agent->runningAsConsole = 1; }
MeshAgent_Start(agent, argc, argv);
retCode = agent->exitCode;
MeshAgent_Destroy(agent);
@@ -1100,7 +1109,7 @@ int main(int argc, char* argv[])
return 0;
}
char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serverid, char** serverurl)
char* getMshSettings(char* fileName, char* selfexe, char** meshname, char** meshid, char** serverid, char** serverurl)
{
char* importFile;
int eq, importFileLen;
@@ -1109,18 +1118,43 @@ char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serv
*meshname = *meshid = *serverid = *serverurl = NULL;
importFileLen = ILibReadFileFromDiskEx(&importFile, fileName);
if (importFile == NULL) return NULL;
if (importFile == NULL) {
// Could not find the .msh file, see if there is one inside our own executable.
FILE *tmpFile = NULL;
char exeMeshPolicyGuid[] = { 0xB9, 0x96, 0x01, 0x58, 0x80, 0x54, 0x4A, 0x19, 0xB7, 0xF7, 0xE9, 0xBE, 0x44, 0x91, 0x4C, 0x19 };
char tmpHash[16];
fopen_s(&tmpFile, selfexe, "rb");
if (tmpFile == NULL) { return NULL; } // Could not open our own executable
fseek(tmpFile, -16, SEEK_END);
ignore_result(fread(tmpHash, 1, 16, tmpFile)); // Read the GUID
if (memcmp(tmpHash, exeMeshPolicyGuid, 16) == 0) { // If this is the Mesh policy file guid, we found a MSH file
// Found embedded MSH File
fseek(tmpFile, -20, SEEK_CUR);
if (fread((void*)&importFileLen, 1, 4, tmpFile) == 4) { // Read the length of the MSH file
importFileLen = ntohl(importFileLen);
if ((importFileLen >= 20000) || (importFileLen < 1)) { fclose(tmpFile); return NULL; }
fseek(tmpFile, -4 - importFileLen, SEEK_CUR);
if ((importFile = malloc(importFileLen + 1)) == NULL) { fclose(tmpFile); return NULL; }
if (fread(importFile, 1, importFileLen, tmpFile) != importFileLen) { fclose(tmpFile); free(importFile); return NULL; }
importFile[importFileLen] = 0;
}
}
else {
fclose(tmpFile);
return NULL;
}
fclose(tmpFile);
}
pr = ILibParseString(importFile, 0, importFileLen, "\n", 1);
f = pr->FirstResult;
while (f != NULL)
{
while (f != NULL) {
f->datalength = ILibTrimString(&(f->data), f->datalength);
if (f->data[0] != 35) // Checking to see if this line is commented out
{
if (f->data[0] != 35) { // Checking to see if this line is commented out
eq = ILibString_IndexOf(f->data, f->datalength, "=", 1);
if (eq > 0)
{
if (eq > 0) {
char *key, *val;
int keyLen, valLen;
@@ -1145,6 +1179,7 @@ char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serv
return importFile;
}
#ifndef _MINCORE
// Message handler for dialog box.
@@ -1229,11 +1264,11 @@ INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
}
}
if ((mshfile = getMshSettings(fileName, &meshname, &meshid, &serverid, &serverurl)) != NULL)
if ((mshfile = getMshSettings(fileName, selfexe, &meshname, &meshid, &serverid, &serverurl)) != NULL)
{
// Set text in the dialog box
if (strlen(meshid) > 50) { meshid += 2; meshid[42] = 0; }
if (strlen(serverid) > 50) { serverid[42] = 0; }
if (strnlen_s(meshid, 255) > 50) { meshid += 2; meshid[42] = 0; }
if (strnlen_s(serverid, 255) > 50) { serverid[42] = 0; }
SetWindowTextA(GetDlgItem(hDlg, IDC_POLICYTEXT), (meshid != NULL) ? meshname : "(None)");
SetWindowTextA(GetDlgItem( hDlg, IDC_HASHTEXT), (meshid != NULL) ? meshid : "(None)");
SetWindowTextA(GetDlgItem(hDlg, IDC_SERVERLOCATION), (serverurl != NULL) ? serverurl : "(None)");

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ limitations under the License.
#include "ILibDuktapeModSearch.h"
#include "microstack/ILibParsers.h"
#include "microscript/ILibDuktape_Helpers.h"
#include "microscript/duk_module_duktape.h"
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
@@ -204,6 +204,8 @@ void ILibDuktape_ModSearch_Destroy(duk_context *ctx, void *user)
}
void ILibDuktape_ModSearch_Init(duk_context * ctx, void * chain, ILibSimpleDataStore mDB)
{
duk_module_duktape_init(ctx);
duk_push_heap_stash(ctx); // [stash]
duk_push_pointer(ctx, chain); // [stash][chain]
duk_put_prop_string(ctx, -2, ILibDuktape_Context_Chain); // [stash]

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "ILibDuktape_ChildProcess.h"
#include "ILibDuktapeModSearch.h"
@@ -100,6 +116,7 @@ duk_ret_t ILibDuktape_ChildProcess_Kill(duk_context *ctx)
ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUSH(duk_context *ctx, ILibProcessPipe_Process mProcess, void *callback)
{
duk_push_object(ctx); // [ChildProcess]
ILibDuktape_WriteID(ctx, "childProcess.subProcess");
duk_push_pointer(ctx, mProcess); // [ChildProcess][ptr]
duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Process); // [ChildProcess]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_ChildProcess_SubProcess)); // [ChildProcess][buffer]
@@ -121,21 +138,21 @@ ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUS
ILibDuktape_CreateInstanceMethod(ctx, "kill", ILibDuktape_ChildProcess_Kill, 0);
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.stdout");
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdout");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdOut = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause, ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stdout");
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.stderr");
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stderr");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdErr = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause, ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stderr");
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess.stdin");
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdin");
duk_dup(ctx, -2);
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
@@ -231,6 +248,7 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "childProcess");
duk_push_pointer(ctx, (void*)ILibProcessPipe_Manager_Create(chain));
duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Manager);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ChildProcess_Manager_Finalizer);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILIBDUKTAPE_CHILDPROCESS__
#define __ILIBDUKTAPE_CHILDPROCESS__

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
@@ -38,7 +54,6 @@ typedef struct ILibDuktape_DGRAM_DATA
void *socketObject;
void *dgramObject;
void *chain;
void *OnClose, *OnError, *OnListening, *OnMessage, *OnSendOK;
ILibAsyncUDPSocket_SocketModule *mSocket;
}ILibDuktape_DGRAM_DATA;
typedef enum ILibDuktape_DGRAM_Config
@@ -68,34 +83,39 @@ void ILibDuktape_Dgram_Socket_OnData(ILibAsyncUDPSocket_SocketModule socketModul
ILibDuktape_DGRAM_DATA* ptrs = (ILibDuktape_DGRAM_DATA*)user;
if (ptrs != NULL && ptrs->ctx != NULL && ptrs->OnMessage != NULL)
if (ptrs != NULL && ptrs->ctx != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnMessage); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [func][this]
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [this]
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
duk_swap_top(ptrs->ctx, -2); // [emit][this]
duk_push_string(ptrs->ctx, "message"); // [emit][this][message]
duk_push_external_buffer(ptrs->ctx);
duk_config_buffer(ptrs->ctx, -1, buffer, (duk_size_t)bufferLength); // [func][this][buffer]
duk_push_object(ptrs->ctx); // [func][this][buffer][rinfo]
duk_push_string(ptrs->ctx, remoteInterface->sin6_family == AF_INET ? "IPv4" : "IPv6"); // [func][this][buffer][rinfo][family]
duk_put_prop_string(ptrs->ctx, -2, "family"); // [func][this][buffer][rinfo]
duk_push_string(ptrs->ctx, ILibRemoteLogging_ConvertAddress((struct sockaddr*)remoteInterface)); // [func][this][buffer][rinfo][address]
duk_put_prop_string(ptrs->ctx, -2, "address"); // [func][this][buffer][rinfo]
duk_push_int(ptrs->ctx, (int)ntohs(remoteInterface->sin6_port)); // [func][this][buffer][rinfo][port]
duk_put_prop_string(ptrs->ctx, -2, "port"); // [func][this][buffer][rinfo]
duk_config_buffer(ptrs->ctx, -1, buffer, (duk_size_t)bufferLength); // [emit][this][message][buffer]
duk_push_object(ptrs->ctx); // [emit][this][message][buffer][rinfo]
duk_push_string(ptrs->ctx, remoteInterface->sin6_family == AF_INET ? "IPv4" : "IPv6"); // [emit][this][message][buffer][rinfo][family]
duk_put_prop_string(ptrs->ctx, -2, "family"); // [emit][this][message][buffer][rinfo]
duk_push_string(ptrs->ctx, ILibRemoteLogging_ConvertAddress((struct sockaddr*)remoteInterface)); // [emit][this][message][buffer][rinfo][address]
duk_put_prop_string(ptrs->ctx, -2, "address"); // [emit][this][message][buffer][rinfo]
duk_push_int(ptrs->ctx, (int)ntohs(remoteInterface->sin6_port)); // [emit][this][message][buffer][rinfo][port]
duk_put_prop_string(ptrs->ctx, -2, "port"); // [emit][this][message][buffer][rinfo]
duk_push_int(ptrs->ctx, bufferLength);
duk_put_prop_string(ptrs->ctx, -2, "size");
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "dgram.message() dispatch error"); }
if (duk_pcall_method(ptrs->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "dgram.message() dispatch error"); }
duk_pop(ptrs->ctx); // ...
}
}
void ILibDuktape_Dgram_Socket_OnSendOK(ILibAsyncUDPSocket_SocketModule socketModule, void *user1, void *user2)
{
ILibDuktape_DGRAM_DATA* ptrs = (ILibDuktape_DGRAM_DATA*)user1;
if (ptrs != NULL && ptrs->ctx != NULL && ptrs->OnSendOK != NULL)
if (ptrs != NULL && ptrs->ctx != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnSendOK); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "net.dgram.socket.onSendOk"); }
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [this]
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
duk_swap_top(ptrs->ctx, -2); // [emit][this]
duk_push_string(ptrs->ctx, "flushed"); // [emit][this][flushed]
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "net.dgram.socket.onSendOk"); }
duk_pop(ptrs->ctx); // ...
}
}
@@ -201,13 +221,14 @@ duk_ret_t ILibDuktape_DGram_Socket_bind(duk_context *ctx)
#endif
}
if (ptrs->OnListening != NULL)
{
duk_push_heapptr(ctx, ptrs->OnListening); // [func]
duk_push_heapptr(ctx, ptrs->socketObject); // [func][this]
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(ctx); }
duk_pop(ctx); // ...
}
duk_push_heapptr(ctx, ptrs->socketObject); // [this]
duk_get_prop_string(ctx, -1, "emit"); // [this][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "listening"); // [emit][this][listening]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ctx); }
duk_pop(ctx); // ...
return 0;
}
@@ -352,12 +373,14 @@ duk_ret_t ILibDuktape_DGram_send(duk_context *ctx)
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "net.dgram.send.callback(): Error "); }
duk_pop(ctx); // ...
}
else if(ptrs->OnError != NULL)
else
{
duk_push_heapptr(ctx, ptrs->OnError); // [func]
duk_push_heapptr(ctx, ptrs->socketObject); // [func][this]
duk_push_heapptr(ctx, ptrs->socketObject); // [this]
duk_get_prop_string(ctx, -1, "emit"); // [this][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "error"); // [emit][this][error]
duk_push_error_object(ctx, DUK_ERR_TYPE_ERROR, "net.dgram.send(): Attempted to send on a closed socket");
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "net.dgram.onError(): Error "); }
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "net.dgram.onError(): Error "); }
duk_pop(ctx); // ...
}
break;
@@ -433,11 +456,11 @@ duk_ret_t ILibDuktape_DGram_createSocket(duk_context *ctx)
ptrs->dgramObject = dgram;
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "close", &(ptrs->OnClose));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "error", &(ptrs->OnError));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "listening", &(ptrs->OnListening));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "message", &(ptrs->OnMessage));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "flushed", &(ptrs->OnSendOK));
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "close");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "listening");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "message");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "flushed");
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "config", config, "bind", ILibDuktape_DGram_Socket_bind, DUK_VARARGS);
@@ -459,6 +482,7 @@ duk_ret_t ILibDuktape_DGram_createSocket(duk_context *ctx)
void ILibDuktape_DGram_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [dgram]
ILibDuktape_WriteID(ctx, "dgram");
duk_push_pointer(ctx, chain); // [dgram][chain]
duk_put_prop_string(ctx, -2, ILibDuktape_DGRAM_CHAIN); // [dgram]
ILibDuktape_CreateInstanceMethod(ctx, "createSocket", ILibDuktape_DGram_createSocket, DUK_VARARGS);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef ___ILibDuktape_Dgram___
#define ___ILibDuktape_Dgram___

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "duktape.h"
#include "ILibDuktape_Helpers.h"
#include "ILibParsers_Duktape.h"

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILibDuktape_EncryptionStream__
#define __ILibDuktape_EncryptionStream__

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILibDuktape_EVENT_EMITTER__
#define __ILibDuktape_EVENT_EMITTER__
@@ -22,17 +38,18 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_conte
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromObject(duk_context *ctx, void *objHeapptr);
void ILibDuktape_EventEmitter_Init(duk_context *ctx);
void ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter *emitter); // Removes all event handlers/dispatchers
int ILibDuktape_EventEmitter_GetEventCount(ILibDuktape_EventEmitter *emitter);
void ILibDuktape_EventEmitter_RemoveAllListeners(ILibDuktape_EventEmitter *emitter, char *eventName); // Invokes JavaScript method EventEmitter.removeAllListeners()
void ILibDuktape_EventEmitter_CreateEvent(ILibDuktape_EventEmitter *emitter, char *eventName, void **hptr); // Create Event with hybrid dispatcher
void ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter *emitter, char *eventName); // Create Event with virtual dispatcher
void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr); // Remove native callback pointer
int ILibDuktape_EventEmitter_AddEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr); // Add Callback after the fact
int ILibDuktape_EventEmitter_AddSink(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_Handler handler); // Add Native Event Handler
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler 'once'
int ILibDuktape_EventEmitter_AddOnceEx(ILibDuktape_EventEmitter *emitter, char *eventName, duk_c_function func, duk_idx_t funcArgs);
int ILibDuktape_EventEmitter_AddOnceEx3(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
int ILibDuktape_EventEmitter_PrependOnce(duk_context *ctx, duk_idx_t i, char *eventName, duk_c_function func);
int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, char *eventName);
#define ILibDuktape_EventEmitter_HasListenersEx(ctx, idx, eventName) ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter_GetEmitter(ctx, idx), eventName)
#define ILibDuktape_EventEmitter_AddOnceEx2(ctx, idx, eventName, func, argCount) ILibDuktape_EventEmitter_AddOnceEx3(ctx, idx, eventName, func)
#define ILibDuktape_EventEmitter_SetupEmit(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "emit");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "ILibDuktape_HECI.h"
#include "ILibDuktapeModSearch.h"
#include "ILibDuktape_Helpers.h"
@@ -220,7 +236,7 @@ duk_ret_t ILibDuktape_HECI_SessionFinalizer(duk_context *ctx)
void ILibDuktape_HECI_Session_EmitErrorEvent(void *chain, void *session)
{
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitErrorEvent, session); }
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitErrorEvent, session); return; }
ILibDuktape_HECI_Session *s = (ILibDuktape_HECI_Session*)session;
duk_context *ctx = s->stream->readableStream->ctx;
@@ -234,7 +250,7 @@ void ILibDuktape_HECI_Session_EmitErrorEvent(void *chain, void *session)
}
void ILibDuktape_HECI_Session_EmitStreamReady(void *chain, void *session)
{
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitStreamReady, session); }
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitStreamReady, session); return; }
ILibDuktape_DuplexStream_Ready(((ILibDuktape_HECI_Session*)session)->stream);
}
@@ -278,7 +294,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
DWORD bytesWritten;
BOOL result = TRUE;
#else
size_t bytesWritten;
ssize_t bytesWritten;
#endif
while (ILibQueue_GetCount(session->PendingWrites) > 0)
@@ -662,6 +678,7 @@ duk_ret_t ILibDuktape_HECI_Session_connect(duk_context *ctx)
duk_ret_t ILibDuktape_HECI_create(duk_context *ctx)
{
duk_push_object(ctx); // [Session]
ILibDuktape_WriteID(ctx, "heci.session");
ILibDuktape_HECI_Push(ctx, NULL); // [Session][HECI]
duk_dup(ctx, -2); // [Session][HECI][Session]
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_Parent); // [Session][HECI]
@@ -939,7 +956,7 @@ void ILibDuktape_HECI_PostSelect(void* object, int slct, fd_set *readset, fd_set
}
if (FD_ISSET(h->descriptor, writeset))
{
printf("Writeset\n");
ILibDuktape_HECI_Session_WriteHandler_Process(h->session);
}
}
void ILibDuktape_HECI_Destroy(void *object)
@@ -957,6 +974,7 @@ void ILibDuktape_HECI_Destroy(void *object)
void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [HECI]
ILibDuktape_WriteID(ctx, "heci");
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HECI_Finalizer);
#ifdef WIN32

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __DUKTAPEHECI__
#define __DUKTAPEHECI__

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -39,6 +39,14 @@ struct sockaddr_in6 duktape_internalAddress;
#define ILibDuktape_Memory_AllocTable "\xFF_MemoryAllocTable"
#define ILibDuktape_ObjectStashKey "\xFF_ObjectStashKey"
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i)
{
int retVal = -1;
duk_inspect_value(ctx, i);
retVal = Duktape_GetIntPropertyValue(ctx, -1, "refc", -1);
duk_pop(ctx);
return(retVal-1);
}
void ILibDuktape_Push_ObjectStash(duk_context *ctx)
{
if (duk_has_prop_string(ctx, -1, ILibDuktape_ObjectStashKey))
@@ -299,7 +307,7 @@ void ILibDuktape_CreateEventWithSetterEx(duk_context *ctx, char *propName, duk_c
duk_push_string(ctx, propName); // [obj][prop]
duk_push_c_function(ctx, setterMethod, 1); // [obj][prop][setFunc]
duk_push_string(ctx, propName); // [obj][prop][setFunc][name]
duk_put_prop_string(ctx, -2, "name"); // [obj][prop][setFunc]
duk_put_prop_string(ctx, -2, "propName"); // [obj][prop][setFunc]
duk_def_prop(ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_SETTER); // [obj]
}
void ILibDuktape_CreateEventWithSetter(duk_context *ctx, char *propName, char *propNamePtr, void **hptr)
@@ -333,6 +341,7 @@ void ILibDuktape_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEve
duk_push_heap_stash(ctx); // [g]
duk_push_object(ctx); // [g][obj]
ILibDuktape_WriteID(ctx, "Mesh.ScriptContainer.heapFinalizer");
duk_push_pointer(ctx, user); // [g][obj][user]
duk_put_prop_string(ctx, -2, "user"); // [g][obj]
duk_push_pointer(ctx, handler); // [g][obj][handler]
@@ -362,19 +371,6 @@ int ILibDuktape_Process_GetExitCode(duk_context *ctx)
return(retVal);
}
ILibDuktape_EventEmitter *ILibDuktape_Process_GetEventEmitter(duk_context *ctx)
{
ILibDuktape_EventEmitter *retVal = NULL;
duk_push_global_object(ctx); // [g]
if (duk_has_prop_string(ctx, -1, "process"))
{
duk_get_prop_string(ctx, -1, "process"); // [g][process]
retVal = ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx);
duk_pop(ctx); // [g]
}
duk_pop(ctx); // ...
return retVal;
}
void *ILibDuktape_GetProcessObject(duk_context *ctx)
{
@@ -420,7 +416,7 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
void *j = ILibDuktape_GetProcessObject(ctx);
ILibDuktape_EventEmitter *emitter;
if (strcmp(errmsg, "Process.exit() forced script termination") == 0) { return; }
if (ILibString_IndexOf(errmsg, (int)errmsgLen, "Process.exit() forced script termination", 40) >= 0) { return; }
duk_push_heapptr(ctx, j); // [process]
emitter = ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx);
@@ -454,7 +450,7 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
duk_get_prop_string(emitter->ctx, -1, "emit"); // [process][emit]
duk_swap_top(emitter->ctx, -2); // [emit][this]
duk_push_string(emitter->ctx, "uncaughtException"); // [emit][this][eventName]
duk_push_error_object(emitter->ctx, DUK_ERR_UNCAUGHT_ERROR, "%s", dest);
duk_push_error_object(emitter->ctx, DUK_ERR_ERROR, "%s", dest);
duk_pcall_method(emitter->ctx, 2);
duk_pop(emitter->ctx); // ...
}
@@ -533,18 +529,11 @@ duk_ret_t ILibDuktape_IndependentFinalizer_Dispatch(duk_context *ctx)
handler(ctx, duk_get_heapptr(ctx, -1));
return 0;
}
void ILibDuktape_CreateIndependentFinalizer(duk_context *ctx, ILibDuktape_IndependentFinalizerHandler handler)
{
char tmp[255];
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, handler); // [obj][ptr]
duk_put_prop_string(ctx, -2, "ptr"); // [obj]
duk_dup(ctx, -2); // [obj][parent]
duk_put_prop_string(ctx, -2, "parent"); // [obj]
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_IndependentFinalizer_Dispatch);
sprintf_s(tmp, sizeof(tmp), "\xFF_%s", Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));
duk_put_prop_string(ctx, -2, tmp);
void ILibDuktape_CreateFinalizer(duk_context *ctx, duk_c_function func)
{
ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_PrependOnce(ctx, -1, "~", func);
}
duk_ret_t ILibDuktape_CreateProperty_InstanceMethod_Sink(duk_context *ctx)
{
@@ -630,10 +619,14 @@ int ILibDuktape_IsPointerValid(void *chain, void *ptr)
{
return(ILibHashtable_Get(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0) == NULL ? 0 : 1);
}
void ILibDuktape_PointerValidation_Finalizer(duk_context *ctx, void *obj)
duk_ret_t ILibDuktape_PointerValidation_Finalizer(duk_context *ctx)
{
duk_push_this(ctx);
void *chain = Duktape_GetChain(ctx);
void *obj = duk_get_heapptr(ctx, -1);
ILibDuktape_InValidatePointer(chain, obj);
duk_pop(ctx);
return(0);
}
void ILibDuktape_PointerValidation_Init(duk_context *ctx)
{
@@ -642,7 +635,7 @@ void ILibDuktape_PointerValidation_Init(duk_context *ctx)
{
// Not set up yet, so set it up
ILibDuktape_ValidatePointer(chain, duk_get_heapptr(ctx, -1));
ILibDuktape_CreateIndependentFinalizer(ctx, ILibDuktape_PointerValidation_Finalizer);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_PointerValidation_Finalizer);
}
}
duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx)
@@ -664,14 +657,17 @@ duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx)
}
}
duk_push_heap_stash(ctx); // [immediate][array][stash]
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(duk_get_heapptr(ctx, -3)));
if (userCallback != NULL) { userCallback(ctx, args, argsLen); }
duk_push_heap_stash(ctx); // [stash]
duk_push_this(ctx); // [stash][immediate]
duk_del_prop_string(ctx, -2, Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));
return(0);
}
void ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback)
void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback)
{
void *retval = NULL;
int i = 0;
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "setImmediate"); // [g][setImmediate]
@@ -690,13 +686,15 @@ void ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDukt
++i;
}
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => immediate(): "); duk_pop(ctx); return; }
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => immediate(): "); duk_pop(ctx); return(NULL); }
// [immediate]
retval = duk_get_heapptr(ctx, -1); // [immediate]
duk_push_heap_stash(ctx); // [immediate][stash]
duk_swap_top(ctx, -2); // [stash][immediate]
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));// [stash]
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(retval)); // [stash]
duk_pop(ctx); // ...
return(retval);
}
void ILibDuktape_CreateInstanceMethodWithProperties(duk_context *ctx, char *funcName, duk_c_function funcImpl, duk_idx_t numArgs, unsigned int propertyCount, ...)
{

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -61,7 +61,6 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
duk_ret_t ILibDuktape_Error(duk_context *ctx, char *format, ...);
typedef void(*ILibDuktape_IndependentFinalizerHandler)(duk_context *ctx, void *object);
void ILibDuktape_CreateIndependentFinalizer(duk_context *ctx, ILibDuktape_IndependentFinalizerHandler handler);
int ILibDuktape_Process_GetExitCode(duk_context *ctx);
void ILibDuktape_CreateEventWithGetter(duk_context *ctx, char *propName, duk_c_function getterMethod);
@@ -86,7 +85,7 @@ void ILibDuktape_CreateProperty_InstanceMethod(duk_context *ctx, char *methodNam
void ILibDuktape_CreateProperty_InstanceMethodEx(duk_context *ctx, char *methodName, void *funcHeapPtr);
void ILibDuktape_CreateReadonlyProperty(duk_context *ctx, char *propName);
#define ILibDuktape_CreateReadonlyProperty_int(ctx, propName, propValue) duk_push_int(ctx, propValue);ILibDuktape_CreateReadonlyProperty(ctx, propName)
#define ILibDuktape_CreateFinalizer(context, funcImpl) duk_push_c_function(context, funcImpl, 1); duk_set_finalizer(context, -2);
void ILibDuktape_CreateFinalizer(duk_context *ctx, duk_c_function func);
void *ILibDuktape_Memory_Alloc(duk_context *ctx, duk_size_t size);
void *ILibDuktape_Memory_AllocEx(duk_context *ctx, duk_idx_t index, duk_size_t size);
@@ -102,7 +101,8 @@ int ILibDuktape_IsPointerValid(void *chain, void *ptr);
#define ILibDuktape_InValidateHeapPointer(ctx, objIdx) ILibDuktape_InValidatePointer(Duktape_GetChain(ctx), duk_get_heapptr(ctx, objIdx))
typedef void(*ILibDuktape_ImmediateHandler)(duk_context *ctx, void ** args, int argsLen);
void ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback);
void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback);
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i);
#define ILibDuktape_WriteID(ctx, id) duk_push_string(ctx, id);duk_put_prop_string(ctx, -2, ILibDuktape_OBJID)

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -29,7 +45,7 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
#define ILibDuktape_CR2Agent "\xFF_CR2Agent"
#define ILibDuktape_CR2HTTPStream "\xFF_CR2HTTPStream"
#define ILibDuktape_CR2TLSStream "\xFF_CR2TLSStream"
#define ILibDuktape_CR2WS "\xFF_ClientRequest2WS"
#define ILibDuktape_CR2Transform "\xFF_CR2Transform"
#define ILibDuktape_FUNC "\xFF_FUNC"
#define IILibDuktape_HTTP_HoldingQueue "\xFF_HoldingQueue"
#define ILibDuktape_Http_Server_FixedBuffer "\xFF_Http_Server_FixedBuffer"
@@ -41,7 +57,9 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
#define ILibDuktape_HTTP2PipedWritable "\xFF_HTTP2PipedWritable"
#define ILibDuktape_HTTPStream2Data "\xFF_HTTPStream2Data"
#define ILibDuktape_HTTPStream2HTTP "\xFF_HTTPStream2HTTP"
#define ILibDuktape_HTTPStream2Socket "\xFF_HTTPStream2Socket"
#define ILibDuktape_IMSG2HttpStream "\xFF_IMSG2HttpStream"
#define ILibDuktape_IMSG2Ptr "\xFF_IMSG2Ptr"
#define ILibDuktape_IMSG2SR "\xFF_IMSG2ServerResponse"
#define ILibDuktape_NS2HttpServer "\xFF_Http_NetServer2HttpServer"
#define ILibDuktape_Options2ClientRequest "\xFF_Options2ClientRequest"
@@ -52,16 +70,17 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
#define ILibDuktape_Socket2CR "\xFF_Socket2CR"
#define ILibDuktape_Socket2HttpServer "\xFF_Socket2HttpServer"
#define ILibDuktape_Socket2HttpStream "\xFF_Socket2HttpStream"
#define ILibDuktape_Socket2DiedListener "\xFF_Socket2DiedListener"
#define ILibDuktape_Socket2TLS "\xFF_Socket2TLS"
#define ILibDuktape_SR2HttpStream "\xFF_ServerResponse2HttpStream"
#define ILibDuktape_SR2ImplicitHeaders "\xFF_ServerResponse2ImplicitHeaders"
#define ILibDuktape_SR2State "\xFF_ServerResponse2State"
#define ILibDuktape_SRUSER "\xFF_SRUSER"
#define ILibDuktape_SR2WS "\xFF_Http_ServerResponse2WS"
#define ILibDuktape_TLS2CR "\xFF_TLS2CR"
#define ILibDuktape_WebSocket_Client ((void*)0x01)
#define ILibDuktape_WebSocket_Server ((void*)0x02)
#define ILibDuktape_WebSocket_StatePtr "\xFF_WebSocketState"
#define ILibDuktape_WSENC2WS "\xFF_WSENC2WS"
#define ILibDuktape_WS2CR "\xFF_WS2ClientRequest"
#define ILibDuktape_WSDEC2WS "\xFF_WSDEC2WS"
@@ -73,6 +92,8 @@ typedef struct ILibDuktape_Http_ClientRequest_WriteData
int noMoreWrites;
int headersFinished;
int contentLengthSpecified;
int needRetry;
int retryCounter;
size_t bufferWriteLen;
size_t bufferLen;
}ILibDuktape_Http_ClientRequest_WriteData;
@@ -90,6 +111,7 @@ typedef struct ILibDuktape_HttpStream_Data
void *WCDO;
void *chain;
int ConnectMethod;
int endPropagated;
}ILibDuktape_HttpStream_Data;
typedef struct ILibDuktape_HttpStream_ServerResponse_State
@@ -129,6 +151,9 @@ typedef struct ILibDuktape_WebSocket_State
void *ObjectPtr; // Used to emit Ping/Pong events
duk_context *ctx; // Used to emit Ping/Pong events
int noResume;
int closed;
ILibDuktape_DuplexStream *encodedStream;
ILibDuktape_DuplexStream *decodedStream;
}ILibDuktape_WebSocket_State;
@@ -337,10 +362,10 @@ void ILibDuktape_HttpStream_http_ConvertOptionToSend(duk_context *ctx, void *Obj
while (duk_next(ctx, -1, 1))
{
tmp = (char*)duk_get_lstring(ctx, -2, &len);
if (buffer != NULL) { memcpy_s(buffer + bufferLen, ILibMemory_AllocateA_Size(buffer) - bufferLen, tmp, len); (buffer + bufferLen)[len] = ':'; }
if (buffer != NULL) { memcpy_s(buffer + bufferLen, ILibMemory_AllocateA_Size(buffer) - bufferLen, tmp, len); (buffer + bufferLen)[len] = ':'; (buffer + bufferLen)[len + 1] = ' '; }
if (len == 6 && strncasecmp(tmp, "expect", 6) == 0) { expectSpecified = 1; }
if (len == 14 && strncasecmp(tmp, "content-length", 14) == 0) { data->contentLengthSpecified = 1; }
bufferLen += (len + 1); // ('key:')
bufferLen += (len + 2); // ('key: ')
tmp = (char*)duk_get_lstring(ctx, -1, &len);
if (buffer != NULL) { memcpy_s(buffer + bufferLen, ILibMemory_AllocateA_Size(buffer) - bufferLen, tmp, len); (buffer + bufferLen)[len] = '\r'; (buffer + bufferLen)[len + 1] = '\n'; }
bufferLen += (len + 2); // ('value\r\n')
@@ -382,41 +407,21 @@ void ILibDuktape_HttpStream_http_ConvertOptionToSend(duk_context *ctx, void *Obj
duk_pop_n(ctx, 4); // ...
}
duk_ret_t ILibDuktape_HttpStream_http_OnTLSConnect(duk_context *ctx)
duk_ret_t ILibDuktape_HttpStream_http_WebSocket_closed(duk_context *ctx)
{
duk_push_this(ctx); // [TLS]
// ClientRequest Options => DecryptedTransform
duk_get_prop_string(ctx, -1, ILibDuktape_TLS2CR); // [TLS][ClientRequest]
duk_get_prop_string(ctx, -2, "clear"); // [TLS][ClientRequest][DecryptedTransform]
duk_get_prop_string(ctx, -2, ILibDuktape_CR2Options); // [TLS][ClientRequest][DecryptedTransform][Options]
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -2), duk_get_heapptr(ctx, -1));
// ClientRequest => DecryptedTransform
duk_pop(ctx); // [TLS][ClientRequest][DecryptedTransform]
duk_get_prop_string(ctx, -2, "pipe"); // [TLS][ClientRequest][DecryptedTransform][pipe]
duk_dup(ctx, -3); // [TLS][ClientRequest][DecryptedTransform][pipe][this]
duk_dup(ctx, -3); // [TLS][ClientRequest][DecryptedTransform][pipe][this][DecryptedTransform]
duk_push_object(ctx); // [TLS][ClientRequest][DecryptedTransform][pipe][this][DecryptedTransform][options]
duk_push_false(ctx); duk_put_prop_string(ctx, -2, "end");
if (duk_pcall_method(ctx, 2) != 0) { return(ILibDuktape_Error(ctx, "http.onTlsConnect() => Error calling pipe on Transform Stream: %s", duk_safe_to_string(ctx, -1))); }
duk_pop_2(ctx); // [TLS][ClientRequest]
// TLS EncryptedTransform => HTTP Stream
duk_get_prop_string(ctx, -2, "encrypted"); // [TLS][ClientRequest][EncryptedTransform]
duk_get_prop_string(ctx, -1, "pipe"); // [TLS][ClientRequest][EncryptedTransform][pipe]
duk_swap_top(ctx, -2); // [TLS][ClientRequest][pipe][this]
duk_get_prop_string(ctx, -3, ILibDuktape_CR2HTTPStream);// [TLS][ClientRequest][pipe][this][http]
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onTlsConnect() => Error calling pipe: %s", duk_safe_to_string(ctx, -1))); }
duk_pop(ctx); // [TLS][ClientRequest]
duk_get_prop_string(ctx, -1, ILibDuktape_CR2HTTPStream);// [TLS][ClientRequest][http]
duk_get_prop_string(ctx, -1, "pipe"); // [TLS][ClientRequest][http][pipe]
duk_swap_top(ctx, -2); // [TLS][ClientRequest][pipe][this]
duk_get_prop_string(ctx, -4, "clear"); // [TLS][ClientRequest][http][this][decryptedTransform]
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onTlsConnect() => Error calling pipe: %s", duk_safe_to_string(ctx, -1))); }
duk_push_this(ctx); // [socket]
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2CR))
{
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [socket][CR]
duk_push_undefined(ctx); // [socket][CR][undefined]
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [socket][CR]
duk_pop(ctx); // [socket]
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2CR);
}
duk_get_prop_string(ctx, -1, "unpipe"); // [socket][unpipe]
duk_swap_top(ctx, -2); // [unpipe][this]
duk_call_method(ctx, 0);
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
@@ -436,11 +441,27 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
// We were upgraded to WebSocket, so we need to create a WebSocket Stream, detach the HTTPStream, and emit the event
// Upstream Readable => X => HttpStream
duk_push_this(ctx); // [HTTPStream]
if (duk_has_prop_string(ctx, -1, ILibDuktape_HTTP2CR))
{
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2CR); // [HTTPStream][CR]
duk_del_prop_string(ctx, -1, ILibDuktape_CR2HTTPStream);
duk_pop(ctx); // [HTTPStream]
}
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2PipedReadable); // [HTTPStream][readable]
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
{
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
}
duk_get_prop_string(ctx, -1, "unpipe"); // [HTTPStream][readable][unpipe]
duk_dup(ctx, -2); // [HTTPStream][readable][unpipe][this]
duk_call_method(ctx, 0); // [HTTPStream][readable][...]
duk_pop(ctx); // [HTTPStream][readable]
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [HTTPStream][readable][prepend]
duk_dup(ctx, -2); // [HTTPStream][readable][prepend][this]
duk_push_string(ctx, "close"); // [HTTPStream][readable][prepend][this]['close']
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_WebSocket_closed, DUK_VARARGS);
duk_call_method(ctx, 2); duk_pop(ctx); // [HTTPStream][readable]
duk_push_external_buffer(ctx); // [HTTPStream][readable][ext]
duk_config_buffer(ctx, -1, decodedKey, decodedKeyLen);
@@ -453,8 +474,8 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
duk_remove(ctx, -2); // [HTTPStream][readable][websocket]
duk_get_prop_string(ctx, -3, ILibDuktape_HTTP2CR); // [HTTPStream][readable][websocket][clientRequest]
duk_dup(ctx, -2); // [HTTPStream][readable][websocket][clientRequest][websocket]
duk_put_prop_string(ctx, -2, ILibDuktape_CR2WS); // [HTTPStream][readable][websocket][clientRequest]
//duk_dup(ctx, -2); // [HTTPStream][readable][websocket][clientRequest][websocket]
//duk_put_prop_string(ctx, -2, ILibDuktape_CR2WS); // [HTTPStream][readable][websocket][clientRequest]
duk_put_prop_string(ctx, -2, ILibDuktape_WS2CR); // [HTTPStream][readable][websocket]
// Upstream Readable => WebSocket Encoded
@@ -475,9 +496,10 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
duk_call_method(ctx, 1); // [HTTPStream][websocket][...]
duk_pop(ctx); // [HTTPStream][websocket]
}
duk_get_prop_string(ctx, -1, ILibDuktape_WS2CR); // [HTTPStream][websocket][clientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [HTTPStream][websocket][clientRequest][emit]
duk_swap_top(ctx, -2); // [HTTPStream][websocket][emit][this]
duk_push_string(ctx, "upgrade"); // [HTTPStream][websocket][emit][this][upgrade]
duk_dup(ctx, 0); // [HTTPStream][websocket][emit][this][upgrade][imsg]
@@ -486,7 +508,7 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
duk_remove(ctx, -2); // [HTTPStream][websocket][emit][this][upgrade][imsg][WS_DEC]
duk_push_null(ctx); // [HTTPStream][websocket][emit][this][upgrade][imsg][WS_DEC][null]
duk_call_method(ctx, 4); duk_pop(ctx); // [HTTPStream][websocket]
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
@@ -494,21 +516,34 @@ duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
duk_push_this(ctx); // [imsg]
duk_get_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream); // [imsg][httpstream]
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2CR); // [imsg][httpstream][CR]
duk_del_prop_string(ctx, -3, ILibDuktape_IMSG2HttpStream);
duk_del_prop_string(ctx, -2, ILibDuktape_HTTP2CR);
duk_del_prop_string(ctx, -1, ILibDuktape_CR2HTTPStream);
duk_get_prop_string(ctx, -1, "unpipe"); // [imsg][httpstream][CR][unpipe]
duk_dup(ctx, -2); // [imsg][httpstream][CR][unpipe][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [imsg][httpstream][CR]
duk_get_prop_string(ctx, -1, "socket"); // [imsg][httpstream][CR][socket]
duk_insert(ctx, -4); // [socket][imsg][httpstream][CR]
duk_push_undefined(ctx); // [socket][imsg][httpstream][CR][undefined]
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [socket][imsg][httpstream][CR]
if (Duktape_GetBooleanProperty(ctx, -2, "connectionCloseSpecified", 0) != 0)
{
// We cant persist this connection, so close the socket.
// Agent is already listening for the 'close' event, so it'll cleanup automatically
duk_get_prop_string(ctx, -1, "socket"); // [imsg][httpstream][CR][socket]
duk_get_prop_string(ctx, -1, "end"); // [imsg][httpstream][CR][socket][end]
duk_swap_top(ctx, -2); // [imsg][httpstream][CR][end][this]
duk_dup(ctx, -4); // [socket][imsg][httpstream][CR][socket]
duk_get_prop_string(ctx, -1, "end"); // [socket][imsg][httpstream][CR][socket][end]
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][end][this]
duk_call_method(ctx, 0);
return(0);
}
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [imsg][httpstream][CR][Agent]
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [imsg][httpstream][CR][Agent][keepSocketAlive]
duk_swap_top(ctx, -2); // [imsg][httpstream][CR][keepSocketAlive][this]
duk_get_prop_string(ctx, -3, "socket"); // [imsg][httpstream][CR][keepSocketAlive][this][socket]
duk_call_method(ctx, 1); duk_pop(ctx); // [imsg][httpstream][CR]
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [socket][imsg][httpstream][CR][Agent]
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [socket][imsg][httpstream][CR][Agent][keepSocketAlive]
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][keepSocketAlive][this]
duk_dup(ctx, -6); // [socket][imsg][httpstream][CR][keepSocketAlive][this][socket]
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][imsg][httpstream][CR]
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_responseSink(duk_context *ctx)
@@ -517,8 +552,92 @@ duk_ret_t ILibDuktape_HttpStream_http_responseSink(duk_context *ctx)
duk_dup(ctx, 0); // [httpstream][imsg]
duk_swap_top(ctx, -2); // [imsg][httpstream]
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2HttpStream); // [imsg]
ILibDuktape_EventEmitter_AddOnceEx3(ctx, 0, "end", ILibDuktape_HttpStream_http_endResponseSink);
duk_pop(ctx);
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_SocketDiedPrematurely(duk_context *ctx)
{
duk_push_this(ctx); // [socket]
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [socket][clientRequest]
ILibDuktape_Transform *tf = (ILibDuktape_Transform*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_CR2Transform);
if (tf->target->resumeImmediate != NULL)
{
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "clearImmediate"); // [g][clearImmediate]
duk_swap_top(ctx, -2); // [clearImmediate][this]
duk_push_heapptr(ctx, tf->target->resumeImmediate); // [clearImmediate][this][immedate]
duk_call_method(ctx, 1); duk_pop(ctx); // ...
tf->target->resumeImmediate = NULL;
}
duk_get_prop_string(ctx, -1, "unpipe"); // [socket][clientRequest][unpipe]
duk_dup(ctx, -2); // [socket][clientRequest][unpipe][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [socket][clientRequest]
ILibDuktape_ReadableStream_DestroyPausedData(tf->target);
// Need to specify some stuff, so the request body will go out again
duk_get_prop_string(ctx, -1, ILibDuktape_CR_RequestBuffer); // [socket][clientRequest][buffer]
ILibDuktape_Http_ClientRequest_WriteData *wdata = (ILibDuktape_Http_ClientRequest_WriteData*)Duktape_GetBuffer(ctx, -1, NULL);
++wdata->retryCounter;
wdata->needRetry = 1;
wdata->bufferWriteLen = wdata->bufferLen;
wdata->headersFinished = 0;
duk_pop(ctx); // [socket][clientRequest]
if (wdata->retryCounter < 3)
{
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [socket][clientRequest][agent]
duk_get_prop_string(ctx, -1, "requests"); // [socket][clientReqeust][agent][requests]
duk_get_prop_string(ctx, -4, ILibDuktape_Socket2AgentKey); // [socket][clientRequest][agent][requests][key]
duk_get_prop(ctx, -2); // [socket][clientRequest][agent][requests][array]
if (!duk_is_undefined(ctx, -1))
{
// We need to prepend the clientRequest into the request Queue
duk_get_prop_string(ctx, -1, "unshift"); // [socket][clientRequest][agent][requests][array][unshift]
duk_swap_top(ctx, -2); // [socket][clientRequest][agent][requests][unshift][this]
duk_dup(ctx, -5); // [socket][clientRequest][agent][requests][unshift][this][clientRequest]
duk_call_method(ctx, 1);
}
}
else
{
ILibDuktape_EventEmitter_SetupEmit(ctx, duk_get_heapptr(ctx, -1), "error"); // [emit][this][error]
duk_push_error_object(ctx, DUK_ERR_ERROR, "Too many failed attempts"); // [emit][this][error][err]
duk_call_method(ctx, 2);
}
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_SocketResponseReceived(duk_context *ctx)
{
duk_push_this(ctx); // [httpStream]
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2Socket); // [httpStream][socket]
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [httpStream][socket][CR]
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Options); // [httpStream][socket][CR][Options]
duk_del_prop_string(ctx, -1, ILibDuktape_Options2ClientRequest);
duk_pop_2(ctx); // [httpStream][socket]
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2CR);
duk_get_prop_string(ctx, -1, "removeListener"); // [httpStream][socket][removeListener]
duk_swap_top(ctx, -2); // [httpStream][removeListener][this]
duk_push_string(ctx, "close"); // [httpStream][removeListener][this][close]
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [httpStream][removeListener][this][close][listener]
duk_call_method(ctx, 2);
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_OnSocketClosed(duk_context *ctx)
{
duk_push_this(ctx); // [socket]
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
{
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream); // [socket][stream]
duk_pop(ctx); // [socket]
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
}
duk_pop(ctx); // ...
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
@@ -526,17 +645,54 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
void *httpStream;
duk_dup(ctx, 0); // [socket]
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_SocketDiedPrematurely, DUK_VARARGS);
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [socket]
duk_push_this(ctx); // [socket][clientRequest]
// Register ourselves for the close event, becuase we'll need to put ourselves back in the Queue if the socket dies before we are done
duk_get_prop_string(ctx, -2, "prependOnceListener"); // [socket][clientRequest][prependOnce]
duk_dup(ctx, -3); // [socket][clientRequest][prependOnce][this]
duk_push_string(ctx, "close"); // [socket][clientRequest][prependOnce][this][close]
duk_get_prop_string(ctx, -5, ILibDuktape_Socket2DiedListener); // [socket][clientRequest][prependOnce][this][close][listener]
duk_call_method(ctx, 2); duk_pop(ctx); // [socket][clientRequest]
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2CR); // [socket]
duk_push_this(ctx); // [socket][clientRequest]
if (duk_has_prop_string(ctx, -2, ILibDuktape_Socket2HttpStream))
{
// HTTP and/or TLS was already setup previously
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2HttpStream); // [socket][clientRequest][HTTPStream]
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "write", ILibDuktape_HttpStream_http_SocketResponseReceived);
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2Data); // [socket][clientRequest][HTTPStream][data]
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
ILibWebClient_ResetWCDO(data->WCDO);
if (data->bodyStream != NULL) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); data->bodyStream = NULL; }
duk_pop(ctx); // [socket][clientRequest][HTTPStream]
// We need to change the events to propagate to the new clientRequest instead of the old one
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
duk_push_string(ctx, "response"); // [socket][clientRequest][HTTPStream][remove][this][response]
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
duk_push_string(ctx, "continue"); // [socket][clientRequest][HTTPStream][remove][this][continue]
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
duk_push_string(ctx, "upgrade"); // [socket][clientRequest][HTTPStream][remove][this][upgrade]
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
duk_push_this(ctx); // [socket][clientRequest][HTTPStream][clientRequest]
duk_put_prop_string(ctx, -2, ILibDuktape_HTTP2CR); // [socket][clientRequest][HTTPStream]
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "response", -2, "response");
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "continue", -2, "continue");
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2PipedWritable); // [socket][clientRequest][HTTPStream][destination]
duk_get_prop_string(ctx, -3, ILibDuktape_CR2Options); // [socket][clientRequest][HTTPStream][destination][Options]
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -2), duk_get_heapptr(ctx, -1));
@@ -573,13 +729,14 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "continue", -2, "continue");
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "write", ILibDuktape_HttpStream_http_SocketResponseReceived);
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -3, "close", ILibDuktape_HttpStream_http_OnSocketClosed); // We need to detach HttpStream when socket closes
duk_put_prop_string(ctx, -2, ILibDuktape_CR2HTTPStream); // [socket][clientRequest]
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Options); // [socket][clientRequest][options]
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -3), duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [socket][clientRequest]
// ClientRequest => Socket
duk_get_prop_string(ctx, -1, "pipe"); // [socket][clientRequest][pipe]
duk_swap_top(ctx, -2); // [socket][pipe][this]
@@ -589,6 +746,12 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
if (duk_pcall_method(ctx, 2) != 0) { return(ILibDuktape_Error(ctx, "http.onConnect(): Error Piping with socket ")); }
duk_pop(ctx); // [socket]
// Save this value, so we can unregister 'close' from socket later
duk_push_heapptr(ctx, httpStream); // [socket][httpStream]
duk_dup(ctx, -2); // [socket][httpStream][socket]
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2Socket); // [socket][httpStream]
duk_pop(ctx); // [socket]
// Socket => HttpStream
duk_get_prop_string(ctx, -1, "pipe"); // [socket][pipe]
duk_dup(ctx, -2); // [socket][pipe][this]
@@ -601,8 +764,8 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
duk_get_prop_string(ctx, -1, "pipe"); // [socket][http][pipe]
duk_swap_top(ctx, -2); // [socket][pipe][this]
duk_dup(ctx, -3); // [socket][pipe][this][socket]
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onConnect(): Error calling pipe ")); }
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onConnect(): Error calling pipe ")); }
return(0);
}
duk_ret_t ILibDuktape_HttpStream_http_OnConnectError(duk_context *ctx)
@@ -708,37 +871,7 @@ duk_ret_t ILibDuktape_HttpStream_http_OnConnect(duk_context *ctx)
{
duk_ret_t retVal = 0;
duk_push_this(ctx); // [socket]
duk_get_prop_string(ctx, -1, ILibDuktape_SOCKET2OPTIONS); // [socket][options]
//if (duk_has_prop_string(ctx, -1, "proxy"))
//{
// duk_get_prop_string(ctx, -1, "proxy"); // [socket][options][proxy]
// duk_size_t remoteHostLen;
// char *remoteHost = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, "remoteHost", NULL, &remoteHostLen);
// int remotePort = Duktape_GetIntPropertyValue(ctx, -1, "remotePort", 0);
// if (remoteHost != NULL && remotePort != 0)
// {
// duk_pop_2(ctx); // [socket]
// ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "data", ILibDuktape_HttpStream_http_proxyData);
// duk_get_prop_string(ctx, -1, "write"); // [socket][write]
// duk_swap_top(ctx, -2); // [write][this]
// char *tmp = (char*)ILibMemory_AllocateA((2 * remoteHostLen) + 72);
// sprintf_s(tmp, ILibMemory_AllocateA_Size(tmp), "CONNECT %s:%u HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\n\r\n", remoteHost, remotePort, remoteHost);
// duk_push_string(ctx, tmp); // [write][this][chunk]
// duk_call_method(ctx, 1);
// return(0);
// }
// else
// {
// duk_pop(ctx); // [socket][options]
// }
//}
duk_pop(ctx); // [socket]
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2CR))
{
// Socket was created with passed in createConnection
@@ -781,7 +914,7 @@ void ILibDuktape_HttpStream_http_request_transformPiped(struct ILibDuktape_Trans
ILibDuktape_readableStream_WriteData(sender->target, tmp, tmpLen);
if (data->bufferWriteLen > 0) { ILibDuktape_readableStream_WriteData(sender->target, data->buffer, (int)data->bufferWriteLen); }
}
else if(data->bufferWriteLen > 0)
else if(data->needRetry != 0)
{
if (data->headersFinished)
{
@@ -790,15 +923,27 @@ void ILibDuktape_HttpStream_http_request_transformPiped(struct ILibDuktape_Trans
else
{
data->headersFinished = 1;
tmpLen = sprintf_s(tmp, sizeof(tmp), "Transfer-Encoding: chunked\r\n\r\n%X\r\n", (unsigned int)data->bufferWriteLen);
if (data->contentLengthSpecified)
{
tmpLen = sprintf_s(tmp, sizeof(tmp), "Content-Length: %d\r\n\r\n", (int)data->bufferWriteLen);
}
else
{
tmpLen = sprintf_s(tmp, sizeof(tmp), "Transfer-Encoding: chunked\r\n\r\n%X\r\n", (unsigned int)data->bufferWriteLen);
}
}
ILibDuktape_readableStream_WriteData(sender->target, tmp, tmpLen);
ILibDuktape_readableStream_WriteData(sender->target, data->buffer, (int)data->bufferWriteLen);
ILibDuktape_readableStream_WriteData(sender->target, "\r\n", 2);
free(data->buffer);
data->buffer = NULL;
if (data->bufferWriteLen > 0)
{
ILibDuktape_readableStream_WriteData(sender->target, data->buffer, (int)data->bufferWriteLen);
if (!data->contentLengthSpecified) { ILibDuktape_readableStream_WriteData(sender->target, "\r\n", 2); }
free(data->buffer);
data->buffer = NULL;
}
data->bufferLen = data->bufferWriteLen = 0;
data->needRetry = 0;
}
}
void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform *sender, int Reserved, int flush, char *buffer, int bufferLen, void *user)
@@ -820,6 +965,13 @@ void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform
{
ILibDuktape_readableStream_WriteData(sender->target, buffer, bufferLen);
}
data->contentLengthSpecified = 1;
if (bufferLen > 0)
{
data->buffer = (char*)ILibMemory_Allocate(bufferLen, 0, NULL, NULL);
data->bufferLen = bufferLen;
memcpy_s(data->buffer, bufferLen, buffer, bufferLen);
}
}
else
{
@@ -844,11 +996,12 @@ void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform
}
}
duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
{
char *proto;
duk_size_t protoLen;
int isTLS = 0;
int nargs = duk_get_top(ctx);
if (duk_is_string(ctx, 0))
{
@@ -881,7 +1034,8 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
duk_put_prop_string(ctx, -2, "agent"); // [options][protocol][options]
duk_pop(ctx); // [options][protocol]
}
if ((protoLen == 4 && strncasecmp(proto, "wss:", 4) == 0) || (protoLen == 6 && strncasecmp(proto, "https:", 6) == 0)) { isTLS = 1; }
duk_pop(ctx); // [options]
if (!duk_has_prop_string(ctx, -1, "headers"))
{
@@ -912,15 +1066,16 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
duk_put_prop_string(ctx, -2, ILibDuktape_CR2HTTP); // [clientRequest]
duk_push_false(ctx);
duk_put_prop_string(ctx, -2, ILibDuktape_CR_EndCalled); // [clientRequest]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Http_ClientRequest_WriteData));
duk_put_prop_string(ctx, -2, ILibDuktape_CR_EndCalled); // [clientRequest]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Http_ClientRequest_WriteData)); // [clientRequest][buffer]
ILibDuktape_Http_ClientRequest_WriteData *wdata = (ILibDuktape_Http_ClientRequest_WriteData*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_CR_RequestBuffer);
duk_put_prop_string(ctx, -2, ILibDuktape_CR_RequestBuffer); // [clientRequest]
memset(wdata, 0, sizeof(ILibDuktape_Http_ClientRequest_WriteData));
ILibDuktape_Transform_Init(ctx, ILibDuktape_HttpStream_http_request_transform, ILibDuktape_HttpStream_http_request_transformPiped, wdata);
duk_push_pointer(ctx, ILibDuktape_Transform_Init(ctx, ILibDuktape_HttpStream_http_request_transform, ILibDuktape_HttpStream_http_request_transformPiped, wdata));
duk_put_prop_string(ctx, -2, ILibDuktape_CR2Transform); // [clientRequest]
ILibDuktape_WriteID(ctx, "https.clientRequest");
ILibDuktape_WriteID(ctx, isTLS ? "https.clientRequest" : "http.clientRequest");
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "abort");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "connect");
@@ -930,8 +1085,18 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "timeout");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
if (nargs > 1 && duk_is_function(ctx, 1))
{
duk_get_prop_string(ctx, -1, "once"); // [clientRequest][once]
duk_dup(ctx, -2); // [clientRequest][once][this]
duk_push_string(ctx, "response"); // [clientRequest][once][this][response]
duk_dup(ctx, 1); // [clientRequest][once][this][response][handler]
duk_call_method(ctx, 2); duk_pop(ctx); // [clientRequest]
}
duk_dup(ctx, 0); // [clientRequest][options]
duk_put_prop_string(ctx, -2, ILibDuktape_CR2Options); // [clientReqeust]
@@ -1185,7 +1350,6 @@ duk_ret_t ILibDuktape_HttpStream_http_server_upgradeWebsocket(duk_context *ctx)
duk_get_prop_string(ctx, -1, "webSocketStream"); // [http][constructor]
duk_push_lstring(ctx, keyResult, keyResultLen); // [http][constructor][key]
duk_new(ctx, 1); // [http][wss]
duk_push_this(ctx); // [http][wss][socket]
duk_get_prop_string(ctx, -1, "pipe"); // [http][wss][socket][pipe]
@@ -1311,7 +1475,8 @@ duk_ret_t ILibDuktape_HttpStream_http_server_onConnection(duk_context *ctx)
//ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "close", -1, "close");
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "connect", -1, "connect");
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "request", -1, "request");
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -2, "upgrade", ILibDuktape_HttpStream_http_server_onUpgrade);
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "upgrade") > 0) { ILibDuktape_EventEmitter_AddOnceEx3(ctx, -2, "upgrade", ILibDuktape_HttpStream_http_server_onUpgrade); }
duk_pop(ctx); // [NS][socket][pipe][this][httpStream]
duk_call_method(ctx, 1); duk_pop_2(ctx); // [NS]
@@ -1396,6 +1561,7 @@ duk_ret_t ILibDuktape_HttpStream_http_server_address(duk_context *ctx)
duk_call_method(ctx, 0); // [httpServer][result]
return(1);
}
duk_ret_t ILibDuktape_HttpStream_http_createServer(duk_context *ctx)
{
ILibDuktape_Http_Server *server;
@@ -1430,7 +1596,7 @@ duk_ret_t ILibDuktape_HttpStream_http_createServer(duk_context *ctx)
if (nargs > 0 && duk_is_function(ctx, 0))
{
ILibDuktape_EventEmitter_AddOn(emitter, "request", duk_require_heapptr(ctx, 1));
ILibDuktape_EventEmitter_AddOn(emitter, "request", duk_require_heapptr(ctx, 0));
}
ILibDuktape_CreateInstanceMethod(ctx, "close", ILibDuktape_HttpStream_http_server_close, DUK_VARARGS);
@@ -1451,18 +1617,17 @@ duk_ret_t ILibDuktape_HttpStream_http_createServer(duk_context *ctx)
duk_get_prop_string(ctx, -1, "createServer"); // [server][nettls][createServer]
duk_swap_top(ctx, -2); // [server][createServer][this]
if (nargs > 0 && duk_is_object(ctx, 0))
if (nargs > 0 && duk_is_object(ctx, 0) && !duk_is_function(ctx, 0))
{
// Options was specified
duk_dup(ctx, 0); // [server][createServer][this][options]
}
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_server_onConnection, DUK_VARARGS);
duk_call_method(ctx, (nargs > 0 && duk_is_object(ctx, 0)) ? 2 : 1); // [server][netServer]
duk_call_method(ctx, (nargs > 0 && duk_is_object(ctx, 0) && !duk_is_function(ctx, 0)) ? 2 : 1); // [server][netServer]
duk_dup(ctx, -2); // [server][netServer][server]
duk_put_prop_string(ctx, -2, ILibDuktape_NS2HttpServer); // [server][netServer]
duk_put_prop_string(ctx, -2, ILibDuktape_Http_Server2NetServer); // [server]
return(1);
}
@@ -1547,6 +1712,13 @@ ILibTransport_DoneState ILibDuktape_HttpStream_WriteSink(ILibDuktape_DuplexStrea
return(ILibTransport_DoneState_INCOMPLETE);
}
duk_push_heapptr(DS->readableStream->ctx, DS->ParentObject); // [httpStream]
duk_get_prop_string(DS->readableStream->ctx, -1, "emit"); // [httpStream][emit]
duk_swap_top(DS->readableStream->ctx, -2); // [emit][this]
duk_push_string(DS->readableStream->ctx, "write"); // [emit][this][write]
if (duk_pcall_method(DS->readableStream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(DS->readableStream->ctx, "httpStream.write(): Error dispatching 'write' event "); }
duk_pop(DS->readableStream->ctx); // ...
// We're already on Chain Thread, so we can just directly write
int beginPointer = 0;
int PAUSE = 0;
@@ -1571,7 +1743,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_WriteSink(ILibDuktape_DuplexStrea
duk_swap_top(stream->ctx, -2); // [extBuffer][unshift][this]
duk_push_buffer_object(stream->ctx, -3, 0, (int)bufferLen - beginPointer, DUK_BUFOBJ_NODEJS_BUFFER);// [extBuffer][unshift][this][buffer]
if (duk_pcall_method(stream->ctx, 1) != 0) { MustBuffer = 1; }
duk_pop(stream->ctx); // ...
duk_pop_2(stream->ctx); // ...
}
else
{
@@ -1631,9 +1803,10 @@ void ILibDuktape_HttpStream_EndSink(ILibDuktape_DuplexStream *stream, void *user
{
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)user;
if (data->bodyStream != NULL)
if (data->bodyStream != NULL && data->endPropagated == 0)
{
ILibDuktape_readableStream_WriteEnd(data->bodyStream);
data->endPropagated = 1;
}
}
void ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(void *chain, void *user)
@@ -1786,9 +1959,9 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
tmp->writeStream = state->writeStream;
tmp->endBytes = stream->endBytes;
tmp->chunk = state->chunkSupported;
if (bufferLen > 0) { memcpy_s(tmp->buffer, bufferLen, buffer, bufferLen); }
if (bufferLen > 0) { memcpy_s(tmp->buffer, bufferLen, buffer, bufferLen); tmp->bufferLen = bufferLen; }
ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(NULL, &tmp);
ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(NULL, tmp);
return(ILibTransport_DoneState_COMPLETE);
}
else
@@ -2216,9 +2389,21 @@ void ILibDuktape_HttpStream_ServerResponse_PUSH(duk_context *ctx, void* writeStr
{
ILibDuktape_HttpStream_ServerResponse_State *state;
duk_push_object(ctx); // [resp]
duk_push_heapptr(ctx, httpStream); // [resp][httpStream]
duk_put_prop_string(ctx, -2, ILibDuktape_SR2HttpStream); // [resp]
duk_push_object(ctx); // [resp]
duk_push_heapptr(ctx, httpStream); // [resp][httpStream]
duk_dup(ctx, -1); // [resp][httpStream][dup]
duk_put_prop_string(ctx, -3, ILibDuktape_SR2HttpStream); // [resp][httpStream]
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2HTTP); // [resp][httpStream][http]
duk_get_prop_string(ctx, -1, ILibDuktape_OBJID); // [resp][httpStream][http][id]
duk_remove(ctx, -2); // [resp][httpStream][id]
duk_get_prop_string(ctx, -1, "concat"); // [resp][httpStream][id][concat]
duk_swap_top(ctx, -2); // [resp][httpStream][concat][this]
duk_push_string(ctx, ".serverResponse"); // [resp][httpStream][concat][this][serverResponse]
if (duk_pcall_method(ctx, 1) != 0) { duk_pop(ctx); duk_push_string(ctx, "http[s].serverResponse"); } // [resp][httpStream][http/s.serverResponse]
duk_remove(ctx, -2); // [resp][http/s.serverResponse]
duk_put_prop_string(ctx, -2, ILibDuktape_OBJID); // [resp]
ILibDuktape_PointerValidation_Init(ctx);
ILibDuktape_WriteID(ctx, "http.serverResponse");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HttpStream_ServerResponse_State)); // [resp][state]
@@ -2408,11 +2593,27 @@ duk_ret_t ILibDuktape_HttpStream_IncomingMessage_Digest_ValidatePassword(duk_con
duk_push_int(ctx, retVal);
return(1);
}
duk_ret_t ILibDuktape_HttpStream_IncomingMessage_finalizer(duk_context *ctx)
{
return(0);
}
void ILibDuktape_HttpStream_IncomingMessage_PUSH(duk_context *ctx, ILibHTTPPacket *header, void *httpstream)
{
duk_push_object(ctx); // [message]
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HttpStream_IncomingMessage_finalizer);
duk_push_heapptr(ctx, httpstream); // [message][httpStream]
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2HttpStream); // [message]
duk_dup(ctx, -1); // [message][httpStream][dup]
duk_put_prop_string(ctx, -3, ILibDuktape_IMSG2HttpStream); // [message][httpStream]
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2HTTP); // [message][httpStream][http]
duk_remove(ctx, -2); // [message][http]
duk_get_prop_string(ctx, -1, ILibDuktape_OBJID); // [message][http][id]
duk_get_prop_string(ctx, -1, "concat"); // [message][http][id][concat]
duk_swap_top(ctx, -2); // [message][http][concat][this]
duk_push_string(ctx, ".IncomingMessage"); // [message][http][concat][this][.IncomingMessage]
if (duk_pcall_method(ctx, 1) != 0) { duk_pop(ctx); duk_push_string(ctx, "http[s].IncomingMessage"); }
duk_remove(ctx, -2); // [message][http/s.IncomingMessage]
duk_put_prop_string(ctx, -2, ILibDuktape_OBJID); // [message]
duk_push_object(ctx); // [message][headers]
packetheader_field_node *node = header->FirstField;
while (node != NULL)
@@ -2479,7 +2680,26 @@ void ILibDuktape_HttpStream_DispatchEnd(void *chain, void *user)
}
free(user);
}
void ILibDuktape_HttpStream_ForceDisconnect(duk_context *ctx, void ** args, int argsLen)
{
duk_push_heapptr(ctx, args[0]);
duk_get_prop_string(ctx, -1, "end");
duk_swap_top(ctx, -2);
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "httpStream.OnUpgrade(): "); }
duk_pop(ctx);
}
duk_ret_t ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized(duk_context *ctx)
{
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetPointerProperty(ctx, 0, ILibDuktape_IMSG2Ptr);
if (data != NULL)
{
if (data->endPropagated == 0) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); }
data->endPropagated = 1;
data->bodyStream = NULL;
}
return(0);
}
void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebClient_ReceiveStatus recvStatus, void *user1, void *user2, int *PAUSE)
{
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)user1;
@@ -2525,7 +2745,22 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][upgrade][imsg]
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][request][imsg][rsp]
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2SR);
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->upgrade(): "); }
if (duk_pcall_method(ctx, 2) != 0)
{ ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->upgrade(): "); }
else
{
if (!duk_get_boolean(ctx, -1))
{
// No upgrade listener... Close connection
printf("\n\nNo Upgrade Listener\n");
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { data->DS->writableStream->pipedReadable }, 1, ILibDuktape_HttpStream_ForceDisconnect);
duk_push_heapptr(ctx, imm);
duk_push_heapptr(ctx, data->DS->writableStream->pipedReadable);
duk_put_prop_string(ctx, -2, "r");
duk_pop_2(ctx);
return;
}
}
duk_pop(ctx); // ...
}
else
@@ -2604,15 +2839,27 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
case 101:
duk_push_string(ctx, "upgrade"); // [emit][this][upgrade]
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][upgrade][imsg]
duk_del_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream);
duk_insert(ctx, -4); // [imsg][emit][this][upgrade]
duk_dup(ctx, -4); // [imsg][emit][this][upgrade][imsg]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->upgrade(): "); }
duk_pop(ctx);
duk_pop(ctx);
break;
default:
duk_push_string(ctx, "response"); // [emit][this][response]
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][response][imsg]
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
duk_push_pointer(ctx, data);
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2Ptr);
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized);
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->response(): "); }
duk_pop(ctx);
if (bodyBuffer != NULL && endPointer > 0)
{
ILibDuktape_readableStream_WriteData(data->bodyStream, bodyBuffer + *beginPointer, endPointer);
}
break;
}
}
@@ -2620,6 +2867,7 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
if (data->bodyStream != NULL && recvStatus == ILibWebClient_ReceiveStatus_Complete)
{
ILibDuktape_readableStream_WriteEnd(data->bodyStream);
data->endPropagated = 1;
}
if (recvStatus == ILibWebClient_ReceiveStatus_Complete)
{
@@ -2651,7 +2899,6 @@ duk_ret_t ILibDuktape_HttpStream_Finalizer(duk_context *ctx)
ILibDuktape_InValidateHeapPointer(ctx, 0);
ILibWebClient_DestroyWebClientDataObject(data->WCDO);
return(0);
}
@@ -2702,6 +2949,7 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "clientError");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "request");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "connect");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "write");
data->DS = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_HttpStream_WriteSink, ILibDuktape_HttpStream_EndSink,
NULL, NULL, NULL, data);
@@ -2772,7 +3020,7 @@ void ILibDuktape_RemoveObjFromTable(duk_context *ctx, duk_idx_t tableIdx, char *
duk_ret_t ILibDuktape_HttpStream_Agent_socketEndSink(duk_context *ctx)
{
duk_push_this(ctx); // [socket]
printf("socket has closed: %p\n", duk_get_heapptr(ctx, -1));
//printf("socket has closed: %p\n", duk_get_heapptr(ctx, -1));
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2Agent); // [socket][agent]
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2AgentKey); // [socket][agent][key]
char *key = Duktape_GetBuffer(ctx, -1, NULL);
@@ -2806,10 +3054,10 @@ duk_ret_t ILibDuktape_HttpStream_Agent_socketEndSink(duk_context *ctx)
duk_get_prop_string(ctx, -1, "createConnection"); // [socket][agent][agent][createConnection]
duk_swap_top(ctx, -2); // [socket][agent][createConnection][this]
duk_get_prop_string(ctx, -4, "\xFF_NET_SOCKET2OPTIONS"); // [socket][agent][createConnection][this][options]
duk_call_method(ctx, 1); // [socket][agent][newsocket]
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_OnConnect, DUK_VARARGS); // We need to register here, because TLS/NonTLS have different event names
duk_call_method(ctx, 2); // [socket][agent][newsocket]
duk_swap_top(ctx, -2); // [socket][newsocket][agent]
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2Agent); // [socket][newsocket]
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "connect", ILibDuktape_HttpStream_http_OnConnect);
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "error", ILibDuktape_HttpStream_http_OnConnectError);
}
}
@@ -2882,6 +3130,7 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
duk_dup(ctx, -4); // [key][Agent][requests][request][reuseSocket][this][socket][request]
duk_call_method(ctx, 2); // [key][Agent][requests][request][retVal]
retVal = 1;
duk_pop(ctx); // [key][Agent][requests][request]
}
}
if (retVal == 0)
@@ -2917,6 +3166,11 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
}
void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args, int argsLen)
{
duk_push_this(ctx); // [immediate]
duk_del_prop_string(ctx, -1, "CR");
duk_del_prop_string(ctx, -2, "Socket");
duk_pop(ctx); // ...
duk_push_heapptr(ctx, args[1]); // [clientRequest]
duk_push_heapptr(ctx, args[0]); // [clientRequest][socket]
@@ -2926,6 +3180,7 @@ void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args,
duk_call_method(ctx, 1); duk_pop(ctx); // [clientRequest][socket]
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [clientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [clientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "socket"); // [emit][this][name]
@@ -2936,7 +3191,13 @@ void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args,
duk_ret_t ILibDuktape_HttpStream_Agent_reuseSocket(duk_context *ctx)
{
// Yield to the next loop, before we emit a 'socket' event, because emitting this event before anyone has the clientRequest object is pointless
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, 0), duk_get_heapptr(ctx, 1) }, 2, ILibDuktape_HttpStream_Agent_reuseSocketEx);
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, 0), duk_get_heapptr(ctx, 1) }, 2, ILibDuktape_HttpStream_Agent_reuseSocketEx);
duk_push_heapptr(ctx, imm); // [immediate]
duk_dup(ctx, 1); // [immediate][ClientRequest]
duk_put_prop_string(ctx, -2, "CR"); // [immediate]
duk_dup(ctx, 0); // [immediate][Socket]
duk_put_prop_string(ctx, -2, "Socket"); // [immediate]
duk_pop(ctx);
return(0);
}
duk_ret_t ILibDuktape_HttpStream_Agent_createConnection_eventSink(duk_context *ctx)
@@ -3144,8 +3405,15 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_WriteWebSocketPacket(IL
if (ILibIsRunningOnChainThread(state->chain) != 0)
{
// We're on the Duktape Thread, so we can just call write multiple times, cuz we won't interleave with JavaScript
ILibDuktape_DuplexStream_WriteData(state->encodedStream, header, headerLen);
retVal = ILibDuktape_DuplexStream_WriteData(state->encodedStream, buffer, bufferLen) == 0 ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
if (bufferLen > 0)
{
ILibDuktape_DuplexStream_WriteData(state->encodedStream, header, headerLen);
retVal = ILibDuktape_DuplexStream_WriteData(state->encodedStream, buffer, bufferLen) == 0 ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
}
else
{
retVal = ILibDuktape_DuplexStream_WriteData(state->encodedStream, header, headerLen) == 0 ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
}
}
else
{
@@ -3314,6 +3582,7 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
switch (OPCODE)
{
case WEBSOCKET_OPCODE_CLOSE:
state->closed = 1;
ILibDuktape_DuplexStream_WriteEnd(state->decodedStream);
if (ILibIsRunningOnChainThread(state->chain) != 0 && state->encodedStream->writableStream->pipedReadable != NULL)
{
@@ -3363,7 +3632,7 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
void ILibDuktape_httpStream_webSocket_EncodedEndSink(ILibDuktape_DuplexStream *stream, void *user)
{
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
ILibDuktape_DuplexStream_WriteEnd(state->decodedStream);
if (!state->closed) { ILibDuktape_DuplexStream_WriteEnd(state->decodedStream); }
}
void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *user)
{
@@ -3453,6 +3722,14 @@ void ILibDuktape_httpStream_webSocket_DecodedPauseSink_Chain(void *chain, void *
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
duk_context *ctx = state->encodedStream->writableStream->ctx;
if (state->encodedStream->writableStream->pipedReadable == NULL)
{
// We're not piped yet, so just set a flag, and we'll make sure we don't resume
state->noResume = 1;
return;
}
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
duk_get_prop_string(ctx, -1, "pause"); // [readable][pause]
duk_swap_top(ctx, -2); // [pause][this]
@@ -3485,6 +3762,12 @@ void ILibDuktape_httpStream_webSocket_DecodedResumeSink_Chain(void *chain, void
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
duk_context *ctx = state->encodedStream->writableStream->ctx;
if (state->encodedStream->writableStream->pipedReadable == NULL)
{
state->noResume = 0;
return;
}
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
duk_get_prop_string(ctx, -1, "resume"); // [readable][resume]
duk_swap_top(ctx, -2); // [resume][this]
@@ -3521,6 +3804,17 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_finalizer(duk_context *ctx)
{
void *chain = Duktape_GetChain(ctx);
duk_get_prop_string(ctx, 0, ILibDuktape_WebSocket_StatePtr);
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
if (state->encodedStream->writableStream->pipedReadable != NULL)
{
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
duk_get_prop_string(ctx, -1, "unpipe"); // [readable][unpipe]
duk_swap_top(ctx, -2); // [unpipe][this]
duk_push_heapptr(ctx, state->encodedStream->writableStream->obj); // [unpipe][this][ws]
duk_call_method(ctx, 1); duk_pop(ctx); // ...
}
ILibDuktape_InValidatePointer(chain, Duktape_GetBuffer(ctx, -1, NULL));
return(0);
}
@@ -3544,6 +3838,24 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_sendPong(duk_context *ctx)
ILibDuktape_httpStream_webSocket_WriteWebSocketPacket(state, WEBSOCKET_OPCODE_PONG, NULL, 0, ILibWebClient_WebSocket_FragmentFlag_Complete);
return(0);
}
duk_ret_t ILibDuktape_httpStream_webSocketStream_encodedPiped(duk_context *ctx)
{
// Someone Piped to the Encoded Stream
duk_push_this(ctx); // [ENC]
duk_get_prop_string(ctx, -1, ILibDuktape_WSENC2WS); // [ENC][WS]
duk_get_prop_string(ctx, -1, ILibDuktape_WebSocket_StatePtr); // [ENC][WS][state]
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
if (state->noResume)
{
state->noResume = 0;
duk_push_heapptr(state->ctx, state->encodedStream->writableStream->pipedReadable); // [Readable]
duk_get_prop_string(state->ctx, -1, "pause"); // [Readable][pause]
duk_swap_top(ctx, -2); // [pause][this]
duk_call_method(ctx, 0);
}
return(0);
}
duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
{
@@ -3562,6 +3874,10 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
duk_push_object(ctx); // [WebSocket][Encoded]
ILibDuktape_WriteID(ctx, "http.WebSocketStream.encoded");
state->encodedStream = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_httpStream_webSocket_EncodedWriteSink, ILibDuktape_httpStream_webSocket_EncodedEndSink, ILibDuktape_httpStream_webSocket_EncodedPauseSink, ILibDuktape_httpStream_webSocket_EncodedResumeSink, ILibDuktape_httpStream_webSocket_EncodedUnshiftSink, state);
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_httpStream_webSocketStream_encodedPiped);
duk_dup(ctx, -2); // [WebSocket][Encoded][WebSocket]
duk_put_prop_string(ctx, -2, ILibDuktape_WSENC2WS); // [WebSocket][Encoded]
ILibDuktape_CreateReadonlyProperty(ctx, "encoded"); // [WebSocket]
duk_push_object(ctx); // [WebSocket][Decoded]
ILibDuktape_WriteID(ctx, "http.WebSocketStream.decoded");

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "duktape.h"
#include "ILibDuktapeModSearch.h"
#include "ILibDuktape_Helpers.h"

View File

@@ -1,3 +1,18 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "duktape.h"
#include "ILibDuktapeModSearch.h"
@@ -15,9 +30,6 @@ typedef struct ILibDuktape_NetworkMonitor
ILibDuktape_EventEmitter *emitter;
ILibIPAddressMonitor addressMonitor;
ILibHashtable *addressTable;
void *OnChange;
void *OnAdded;
void *OnRemoved;
}ILibDuktape_NetworkMonitor;
@@ -63,45 +75,31 @@ ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
void ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
duk_context *ctx = (duk_context*)((void**)user)[0];
void *OnEvent = ((void**)user)[1];
char *eventName = (char*)((void**)user)[1];
void *Self = ((void**)user)[2];
ILibHashtable other = (ILibHashtable)((void**)user)[3];
if (ILibHashtable_Get(other, NULL, Key2, Key2Len) == NULL)
{
if (OnEvent != NULL)
{
duk_push_heapptr(ctx, OnEvent); // [func]
duk_push_heapptr(ctx, Self); // [func][this]
duk_push_lstring(ctx, Key2, (duk_size_t)Key2Len); // [func][this][address]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "NetworkMonitor.OnAdd/Remove(): "); }
duk_pop(ctx);
}
ILibDuktape_EventEmitter_SetupEmit(ctx, Self, eventName); // [emit][this][eventName]
duk_push_lstring(ctx, Key2, (duk_size_t)Key2Len); // [emit][this][eventName][address]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "NetworkMonitor.OnAdd/Remove(): "); }
duk_pop(ctx);
}
}
void ILibDuktape_NetworkMonitor_EventSink(ILibIPAddressMonitor sender, void *user)
{
ILibDuktape_NetworkMonitor *nm = (ILibDuktape_NetworkMonitor*)user;
if (nm->OnChange != NULL)
{
duk_push_heapptr(nm->ctx, nm->OnChange); // [func]
duk_push_heapptr(nm->ctx, nm->emitter->object); // [func][this]
if (duk_pcall_method(nm->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(nm->ctx, "NetworkMonitor.change(): "); }
duk_pop(nm->ctx); // ...
}
ILibDuktape_EventEmitter_SetupEmit(nm->ctx, nm->emitter->object, "change"); // [emit][this][change]
if (duk_pcall_method(nm->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(nm->ctx, "NetworkMonitor.change(): "); }
duk_pop(nm->ctx); // ...
ILibHashtable current = ILibDuktape_NetworkMonitor_CreateTable(nm->ctx);
ILibHashtable_Enumerate(current, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, (void*[]){ nm->ctx, "add", nm->emitter->object, nm->addressTable });
ILibHashtable_Enumerate(nm->addressTable, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, (void*[]) { nm->ctx, "remove", nm->emitter->object, current });
if (nm->OnAdded != NULL)
{
void *data[] = { nm->ctx, nm->OnAdded, nm->emitter->object, nm->addressTable };
ILibHashtable_Enumerate(current, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, data);
}
if(nm->OnRemoved != NULL)
{
void *data[] = { nm->ctx, nm->OnRemoved, nm->emitter->object, current };
ILibHashtable_Enumerate(nm->addressTable, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, data);
}
ILibHashtable_Destroy(nm->addressTable);
nm->addressTable = current;
@@ -130,9 +128,9 @@ void ILibDuktape_NetworkMonitor_PUSH(duk_context *ctx, void *chain)
nm->emitter = ILibDuktape_EventEmitter_Create(ctx);
nm->addressMonitor = ILibIPAddressMonitor_Create(chain, ILibDuktape_NetworkMonitor_EventSink, nm);
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "change", &(nm->OnChange));
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "add", &(nm->OnAdded));
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "remove", &(nm->OnRemoved));
ILibDuktape_EventEmitter_CreateEventEx(nm->emitter, "change");
ILibDuktape_EventEmitter_CreateEventEx(nm->emitter, "add");
ILibDuktape_EventEmitter_CreateEventEx(nm->emitter, "remove");
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_NetworkMonitor_Finalizer);
//

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILIBDUKTAPE_NETWORKMONITOR__
#define __ILIBDUKTAPE_NETWORKMONITOR__

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "duktape.h"
#include "ILibDuktape_Helpers.h"
#include "ILibDuktapeModSearch.h"
@@ -9,7 +25,10 @@
#define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS"
#define ILibDuktape_Queue_Ptr "\xFF_Queue"
#define ILibDuktape_Stream_Buffer "\xFF_BUFFER"
#define ILibDuktape_Stream_ReadablePtr "\xFF_ReadablePtr"
int g_displayStreamPipeMessages = 0;
int g_displayFinalizerMessages = 0;
duk_ret_t ILibDuktape_Pollyfills_Buffer_slice(duk_context *ctx)
{
@@ -157,23 +176,23 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_alloc(duk_context *ctx)
}
void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
{
// Polyfill 'Buffer.slice'
duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);// [g][Duktape][Buffer][prototype][func]
duk_put_prop_string(ctx, -2, "readInt32BE"); // [g][Duktape][Buffer][prototype]
duk_pop_3(ctx); // [g]
//// Polyfill 'Buffer.slice'
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
//duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
//duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);// [g][Duktape][Buffer][prototype][func]
//duk_put_prop_string(ctx, -2, "readInt32BE"); // [g][Duktape][Buffer][prototype]
//duk_pop_3(ctx); // [g]
// Polyfill 'Buffer.toString()
duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_toString, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
duk_put_prop_string(ctx, -2, "toString"); // [g][Duktape][Buffer][prototype]
duk_pop_3(ctx); // [g]
//// Polyfill 'Buffer.toString()
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_toString, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
//duk_put_prop_string(ctx, -2, "toString"); // [g][Duktape][Buffer][prototype]
//duk_pop_3(ctx); // [g]
// Polyfill Buffer.from()
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Buffer]
@@ -313,6 +332,31 @@ duk_ret_t ILibDuktape_Polyfills_Console_enableWebLog(duk_context *ctx)
#endif
return (0);
}
duk_ret_t ILibDuktape_Polyfills_Console_displayStreamPipe_getter(duk_context *ctx)
{
duk_push_int(ctx, g_displayStreamPipeMessages);
return(1);
}
duk_ret_t ILibDuktape_Polyfills_Console_displayStreamPipe_setter(duk_context *ctx)
{
g_displayStreamPipeMessages = duk_require_int(ctx, 0);
return(0);
}
duk_ret_t ILibDuktape_Polyfills_Console_displayFinalizer_getter(duk_context *ctx)
{
duk_push_int(ctx, g_displayFinalizerMessages);
return(1);
}
duk_ret_t ILibDuktape_Polyfills_Console_displayFinalizer_setter(duk_context *ctx)
{
g_displayFinalizerMessages = duk_require_int(ctx, 0);
return(0);
}
duk_ret_t ILibDuktape_Polyfills_Console_logRefCount(duk_context *ctx)
{
printf("Reference Count => %s[%p]:%d\n", Duktape_GetStringPropertyValue(ctx, 0, ILibDuktape_OBJID, "UNKNOWN"), duk_require_heapptr(ctx, 0), ILibDuktape_GetReferenceCount(ctx, 0) - 1);
return(0);
}
void ILibDuktape_Polyfills_Console(duk_context *ctx)
{
// Polyfill console.log()
@@ -326,11 +370,12 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx)
duk_dup(ctx, -1); // [g][console][console]
duk_put_prop_string(ctx, -3, "console"); // [g][console]
}
duk_push_c_function(ctx, ILibDuktape_Polyfills_Console_log, DUK_VARARGS); // [g][console][log]
duk_put_prop_string(ctx, -2, "log"); // [g][console]
ILibDuktape_CreateInstanceMethod(ctx, "log", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "enableWebLog", ILibDuktape_Polyfills_Console_enableWebLog, 1);
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayStreamPipeMessages", ILibDuktape_Polyfills_Console_displayStreamPipe_getter, ILibDuktape_Polyfills_Console_displayStreamPipe_setter);
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayFinalizerMessages", ILibDuktape_Polyfills_Console_displayFinalizer_getter, ILibDuktape_Polyfills_Console_displayFinalizer_setter);
ILibDuktape_CreateInstanceMethod(ctx, "logReferenceCount", ILibDuktape_Polyfills_Console_logRefCount, 1);
duk_pop(ctx); // [g]
}
duk_ret_t ILibDuktape_ntohl(duk_context *ctx)
@@ -404,6 +449,14 @@ duk_ret_t ILibDuktape_Polyfills_timer_finalizer(duk_context *ctx)
// Make sure we remove any timers just in case, so we don't leak resources
ILibDuktape_Timer *ptrs;
duk_get_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs);
if (duk_has_prop_string(ctx, 0, "\xFF_callback"))
{
duk_del_prop_string(ctx, 0, "\xFF_callback");
}
if (duk_has_prop_string(ctx, 0, "\xFF_argArray"))
{
duk_del_prop_string(ctx, 0, "\xFF_argArray");
}
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
@@ -415,24 +468,29 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
int argCount, i;
duk_context *ctx = ptrs->ctx;
duk_push_heapptr(ctx, ptrs->callback); // [func]
duk_push_heapptr(ctx, ptrs->object); // [func][this]
duk_push_heapptr(ctx, ptrs->args); // [func][this][argArray]
if (ptrs->timerType == ILibDuktape_Timer_Type_INTERVAL)
{
ILibLifeTime_AddEx(ILibGetBaseTimer(Duktape_GetChain(ptrs->ctx)), ptrs, ptrs->timeout, ILibDuktape_Polyfills_timer_elapsed, NULL);
ILibLifeTime_AddEx(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs, ptrs->timeout, ILibDuktape_Polyfills_timer_elapsed, NULL);
}
else
{
duk_del_prop_string(ctx, -2, "\xFF_callback");
duk_del_prop_string(ctx, -2, "\xFF_argArray");
}
duk_push_heapptr(ptrs->ctx, ptrs->callback); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->object); // [func][this]
duk_push_heapptr(ptrs->ctx, ptrs->args); // [func][this][argArray]
argCount = (int)duk_get_length(ptrs->ctx, -1);
argCount = (int)duk_get_length(ctx, -1);
for (i = 0; i < argCount; ++i)
{
duk_get_prop_index(ptrs->ctx, -1, i); // [func][this][argArray][arg]
duk_swap_top(ptrs->ctx, -2); // [func][this][arg][argArray]
duk_get_prop_index(ctx, -1, i); // [func][this][argArray][arg]
duk_swap_top(ctx, -2); // [func][this][arg][argArray]
}
duk_pop(ptrs->ctx); // [func][this][...arg...]
if (duk_pcall_method(ptrs->ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "timers.onElapsed() callback handler"); }
duk_pop(ctx); // ...
duk_pop(ctx); // [func][this][...arg...]
if (duk_pcall_method(ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "timers.onElapsed() callback handler"); }
duk_pop(ctx); // ...
}
duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
{
@@ -447,6 +505,18 @@ duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
timerType = (ILibDuktape_Timer_Type)duk_get_int(ctx, -1);
duk_push_object(ctx); //[retVal]
switch (timerType)
{
case ILibDuktape_Timer_Type_IMMEDIATE:
ILibDuktape_WriteID(ctx, "Timers.immediate");
break;
case ILibDuktape_Timer_Type_INTERVAL:
ILibDuktape_WriteID(ctx, "Timers.interval");
break;
case ILibDuktape_Timer_Type_TIMEOUT:
ILibDuktape_WriteID(ctx, "Timers.timeout");
break;
}
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_Polyfills_timer_finalizer);
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Timer)); //[retVal][ptrs]
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
@@ -463,13 +533,13 @@ duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
for (argx = ILibDuktape_Timer_Type_IMMEDIATE == timerType ? 1 : 2; argx < nargs; ++argx)
{
duk_dup(ctx, argx); //[retVal][argArray][arg]
duk_put_prop_index(ctx, -2, argx - (ILibDuktape_Timer_Type_IMMEDIATE == timerType ? 1 : 2)); //[retVal][argArray]
duk_put_prop_index(ctx, -2, argx - (ILibDuktape_Timer_Type_IMMEDIATE == timerType ? 1 : 2));//[retVal][argArray]
}
ptrs->args = duk_get_heapptr(ctx, -1);
ptrs->args = duk_get_heapptr(ctx, -1); //[retVal]
duk_put_prop_string(ctx, -2, "\xFF_argArray");
duk_dup(ctx, 0); //[retVal][callback]
duk_put_prop_string(ctx, -2, "\xFF_callback"); //[retVal]
duk_dup(ctx, 0); //[retVal][callback]
duk_put_prop_string(ctx, -2, "\xFF_callback"); //[retVal]
ILibLifeTime_AddEx(ILibGetBaseTimer(chain), ptrs, ptrs->timeout, ILibDuktape_Polyfills_timer_elapsed, NULL);
return 1;
@@ -758,11 +828,179 @@ void ILibDuktape_DynamicBuffer_Push(duk_context *ctx, void *chain)
duk_push_c_function(ctx, ILibDuktape_DynamicBuffer_new, DUK_VARARGS);
}
duk_ret_t ILibDuktape_Polyfills_debugCrash(duk_context *ctx)
{
void *p = NULL;
((int*)p)[0] = 55;
return(0);
}
void ILibDuktape_Stream_PauseSink(struct ILibDuktape_readableStream *sender, void *user)
{
}
void ILibDuktape_Stream_ResumeSink(struct ILibDuktape_readableStream *sender, void *user)
{
int skip = 0;
duk_size_t bufferLen;
duk_push_heapptr(sender->ctx, sender->object); // [stream]
void *func = Duktape_GetHeapptrProperty(sender->ctx, -1, "_read");
duk_pop(sender->ctx); // ...
while (func != NULL && sender->paused == 0)
{
duk_push_heapptr(sender->ctx, sender->object); // [this]
if (!skip && duk_has_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer))
{
duk_get_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer); // [this][buffer]
if ((bufferLen = duk_get_length(sender->ctx, -1)) > 0)
{
// Buffer is not empty, so we need to 'PUSH' it
duk_get_prop_string(sender->ctx, -2, "push"); // [this][buffer][push]
duk_dup(sender->ctx, -3); // [this][buffer][push][this]
duk_dup(sender->ctx, -3); // [this][buffer][push][this][buffer]
duk_remove(sender->ctx, -4); // [this][push][this][buffer]
duk_call_method(sender->ctx, 1); // [this][boolean]
sender->paused = !duk_get_boolean(sender->ctx, -1);
duk_pop(sender->ctx); // [this]
if (duk_has_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer))
{
duk_get_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer); // [this][buffer]
if (duk_get_length(sender->ctx, -1) == bufferLen)
{
// All the data was unshifted
skip = !sender->paused;
}
duk_pop(sender->ctx); // [this]
}
duk_pop(sender->ctx); // ...
}
else
{
// Buffer is empty
duk_pop(sender->ctx); // [this]
duk_del_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer);
duk_pop(sender->ctx); // ...
}
}
else
{
// We need to 'read' more data
duk_push_heapptr(sender->ctx, func); // [this][read]
duk_swap_top(sender->ctx, -2); // [read][this]
if (duk_pcall_method(sender->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(sender->ctx); duk_pop(sender->ctx); break; }
// // [buffer]
duk_push_heapptr(sender->ctx, sender->object); // [buffer][this]
duk_swap_top(sender->ctx, -2); // [this][buffer]
if (duk_has_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer))
{
duk_push_global_object(sender->ctx); // [this][buffer][g]
duk_get_prop_string(sender->ctx, -1, "Buffer"); // [this][buffer][g][Buffer]
duk_remove(sender->ctx, -2); // [this][buffer][Buffer]
duk_get_prop_string(sender->ctx, -1, "concat"); // [this][buffer][Buffer][concat]
duk_swap_top(sender->ctx, -2); // [this][buffer][concat][this]
duk_push_array(sender->ctx); // [this][buffer][concat][this][Array]
duk_get_prop_string(sender->ctx, -1, "push"); // [this][buffer][concat][this][Array][push]
duk_dup(sender->ctx, -2); // [this][buffer][concat][this][Array][push][this]
duk_get_prop_string(sender->ctx, -7, ILibDuktape_Stream_Buffer); // [this][buffer][concat][this][Array][push][this][buffer]
duk_call_method(sender->ctx, 1); duk_pop(sender->ctx); // [this][buffer][concat][this][Array]
duk_get_prop_string(sender->ctx, -1, "push"); // [this][buffer][concat][this][Array][push]
duk_dup(sender->ctx, -2); // [this][buffer][concat][this][Array][push][this]
duk_dup(sender->ctx, -6); // [this][buffer][concat][this][Array][push][this][buffer]
duk_remove(sender->ctx, -7); // [this][concat][this][Array][push][this][buffer]
duk_call_method(sender->ctx, 1); duk_pop(sender->ctx); // [this][concat][this][Array]
duk_call_method(sender->ctx, 1); // [this][buffer]
}
duk_put_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer); // [this]
duk_pop(sender->ctx); // ...
skip = 0;
}
}
}
int ILibDuktape_Stream_UnshiftSink(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user)
{
duk_push_fixed_buffer(sender->ctx, unshiftBytes); // [buffer]
memcpy_s(Duktape_GetBuffer(sender->ctx, -1, NULL), unshiftBytes, sender->unshiftReserved, unshiftBytes);
duk_push_heapptr(sender->ctx, sender->object); // [buffer][stream]
duk_push_buffer_object(sender->ctx, -2, 0, unshiftBytes, DUK_BUFOBJ_NODEJS_BUFFER); // [buffer][stream][buffer]
duk_put_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer); // [buffer][stream]
duk_pop_2(sender->ctx); // ...
return(unshiftBytes);
}
duk_ret_t ILibDuktape_Stream_Push(duk_context *ctx)
{
duk_push_this(ctx); // [stream]
ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr);
duk_get_prop_string(ctx, -1, ILibDuktape_Stream_Buffer); // [stream][buffer]
duk_del_prop_string(ctx, -2, ILibDuktape_Stream_Buffer); // (Deleting here, because unshift will save it again, if necessary)
duk_size_t bufferLen;
char *buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
duk_push_boolean(ctx, !ILibDuktape_readableStream_WriteDataEx(RS, 0, buffer, (int)bufferLen)); // [stream][buffer][retVal]
return(1);
}
duk_ret_t ILibDuktape_Stream_EndSink(duk_context *ctx)
{
duk_push_this(ctx); // [stream]
ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr);
ILibDuktape_readableStream_WriteEnd(RS);
return(0);
}
duk_idx_t ILibDuktape_Stream_newReadable(duk_context *ctx)
{
ILibDuktape_readableStream *RS;
duk_push_object(ctx); // [Readable]
ILibDuktape_WriteID(ctx, "stream.readable");
RS = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_Stream_PauseSink, ILibDuktape_Stream_ResumeSink, ILibDuktape_Stream_UnshiftSink, NULL);
RS->paused = 1;
duk_push_pointer(ctx, RS);
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_ReadablePtr);
ILibDuktape_CreateInstanceMethod(ctx, "push", ILibDuktape_Stream_Push, DUK_VARARGS);
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "end", ILibDuktape_Stream_EndSink);
if (duk_is_object(ctx, 0))
{
void *h = Duktape_GetHeapptrProperty(ctx, 0, "read");
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_read"); }
}
return(1);
}
void ILibDuktape_Stream_Init(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [stream
ILibDuktape_WriteID(ctx, "stream");
ILibDuktape_CreateInstanceMethod(ctx, "Readable", ILibDuktape_Stream_newReadable, DUK_VARARGS);
}
void ILibDuktape_Polyfills_debugGC2(duk_context *ctx, void ** args, int argsLen)
{
if (g_displayFinalizerMessages) { printf("=> GC();\n"); }
duk_gc(ctx, 0);
duk_gc(ctx, 0);
}
duk_ret_t ILibDuktape_Polyfills_debugGC(duk_context *ctx)
{
ILibDuktape_Immediate(ctx, (void*[]) { NULL }, 0, ILibDuktape_Polyfills_debugGC2);
return(0);
}
duk_ret_t ILibDuktape_Polyfills_debug(duk_context *ctx)
{
#ifdef WIN32
if (IsDebuggerPresent()) { __debugbreak(); }
#elif defined(_POSIX)
raise(SIGTRAP);
#endif
return(0);
}
void ILibDuktape_Polyfills_Init(duk_context *ctx)
{
ILibDuktape_ModSearch_AddHandler(ctx, "queue", ILibDuktape_Queue_Push);
ILibDuktape_ModSearch_AddHandler(ctx, "DynamicBuffer", ILibDuktape_DynamicBuffer_Push);
ILibDuktape_ModSearch_AddHandler(ctx, "stream", ILibDuktape_Stream_Init);
// Global Polyfills
duk_push_global_object(ctx); // [g]
@@ -774,6 +1012,9 @@ void ILibDuktape_Polyfills_Init(duk_context *ctx)
ILibDuktape_Polyfills_timer(ctx);
ILibDuktape_CreateInstanceMethod(ctx, "addModule", ILibDuktape_Polyfills_addModule, 2);
ILibDuktape_CreateInstanceMethod(ctx, "_debugCrash", ILibDuktape_Polyfills_debugCrash, 0);
ILibDuktape_CreateInstanceMethod(ctx, "_debugGC", ILibDuktape_Polyfills_debugGC, 0);
ILibDuktape_CreateInstanceMethod(ctx, "_debug", ILibDuktape_Polyfills_debug, 0);
duk_pop(ctx); // ...
}

View File

@@ -1,8 +1,26 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILibDuktape_Polyfills__
#define __ILibDuktape_Polyfills__
#include "duktape.h"
extern int g_displayStreamPipeMessages;
extern int g_displayFinalizerMessages;
void ILibDuktape_Polyfills_Init(duk_context *ctx);
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ limitations under the License.
#include "ILibParsers_Duktape.h"
#include "microstack/ILibParsers.h"
#include "ILibDuktape_EventEmitter.h"
#include "ILibDuktape_Polyfills.h"
#define ILibDuktape_readableStream_WritePipes "\xFF_WritePipes"
@@ -105,6 +106,19 @@ typedef struct ILibDuktape_readableStream_bufferedData
char buffer[];
}ILibDuktape_readableStream_bufferedData;
void ILibDuktape_ReadableStream_DestroyPausedData(ILibDuktape_readableStream *stream)
{
ILibDuktape_readableStream_bufferedData *buffered = (ILibDuktape_readableStream_bufferedData*)stream->paused_data;
ILibDuktape_readableStream_bufferedData *tmp;
while (buffered != NULL)
{
tmp = buffered->Next;
free(buffered);
buffered = tmp;
}
stream->paused_data = NULL;
}
void ILibDuktape_readableStream_WriteData_buffer(ILibDuktape_readableStream *stream, int streamReserved, char *buffer, int bufferLen)
{
ILibDuktape_readableStream_bufferedData *buffered = (ILibDuktape_readableStream_bufferedData*)ILibMemory_Allocate(bufferLen + sizeof(ILibDuktape_readableStream_bufferedData), 0, NULL, NULL);
@@ -137,17 +151,17 @@ void ILibDuktape_readableStream_WriteData_OnData_ChainThread(void *chain, void *
duk_push_external_buffer(stream->ctx); // [ext]
duk_config_buffer(stream->ctx, -1, data->buffer, data->bufferLen);
}
duk_push_heapptr(stream->ctx, stream->OnData); // [ext][func]
duk_push_heapptr(stream->ctx, stream->object); // [ext][func][this]
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "data"); // [ext][emit][this][data]
if (data->Reserved == 0)
{
duk_push_buffer_object(stream->ctx, -3, 0, data->bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [ext][func][this][buffer]
duk_push_buffer_object(stream->ctx, -4, 0, data->bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [ext][emit][this][data][buffer]
}
else
{
duk_push_lstring(stream->ctx, data->buffer, data->bufferLen); // [ext][func][this][buffer/string]
duk_push_lstring(stream->ctx, data->buffer, data->bufferLen); // [ext][emit][this][data][buffer/string]
}
if (duk_pcall_method(stream->ctx, 1) != 0) // [...][retVal]
if (duk_pcall_method(stream->ctx, 2) != 0) // [...][retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
}
@@ -275,6 +289,7 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
{
ILibDuktape_WritableStream *ws = (ILibDuktape_WritableStream*)w->nativeWritable;
ws->Reserved = streamReserved;
ws->endBytes = -1;
switch (ws->WriteSink(ws, buffer, bufferLen, ws->WriteSink_User))
{
case ILibTransport_DoneState_INCOMPLETE:
@@ -333,7 +348,7 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
stream->pipeInProgress = 0;
sem_post(&(stream->pipeLock));
if (stream->OnData != NULL)
if(ILibDuktape_EventEmitter_HasListeners(stream->emitter, "data"))
{
if (ILibIsRunningOnChainThread(stream->chain))
{
@@ -342,17 +357,16 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
duk_push_external_buffer(stream->ctx); // [extBuffer]
duk_config_buffer(stream->ctx, -1, buffer, bufferLen);
}
duk_push_heapptr(stream->ctx, stream->OnData); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "data"); // [extBuffer][emit][this][data]
if (streamReserved == 0)
{
duk_push_buffer_object(stream->ctx, -3, 0, bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][func][this][nodeBuffer]
duk_push_buffer_object(stream->ctx, -4, 0, bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this][data][nodeBuffer]
}
else
{
duk_push_lstring(stream->ctx, buffer, bufferLen); // [func][this][string]
duk_push_lstring(stream->ctx, buffer, bufferLen); // [extBuffer][emit][this][data][string]
}
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
if (duk_pcall_method(stream->ctx, 2) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
}
@@ -377,14 +391,14 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_OnData_ChainThread, tmp);
}
}
else if (stream->PauseHandler != NULL && stream->OnEnd == NULL)
else if (stream->PauseHandler != NULL && ILibDuktape_EventEmitter_HasListeners(stream->emitter, "end") == 0)
{
// If we get here, it means we are writing data, but nobody is going to be receiving it...
// So we need to buffer the data, so when we are resumed later, we can retry
needPause = 1;
ILibDuktape_readableStream_WriteData_buffer(stream, streamReserved, buffer, bufferLen);
}
else if (stream->OnEnd != NULL)
else if (ILibDuktape_EventEmitter_HasListeners(stream->emitter, "end") != 0)
{
return 0;
}
@@ -429,16 +443,11 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
retVal = 0;
}
}
else if (stream->OnEnd != NULL)
else if (ILibDuktape_EventEmitter_HasListeners(stream->emitter, "end") != 0)
{
duk_context *x = stream->ctx;
duk_push_heapptr(stream->ctx, stream->OnEnd); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
}
duk_pop(x); // ...
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "end"); // [emit][this][end]
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
duk_pop(stream->ctx); // ...
retVal = 0;
}
}
@@ -447,16 +456,18 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream)
{
ILibDuktape_readableStream_WriteEnd(stream);
if (stream->OnClose != NULL)
if(ILibDuktape_EventEmitter_HasListeners(stream->emitter, "close")!=0)
{
duk_push_heapptr(stream->ctx, stream->OnClose); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
}
duk_pop(stream->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "close"); // [emit][this][close]
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
duk_pop(stream->ctx); // ...
}
duk_push_heapptr(stream->ctx, stream->object); // [stream]
duk_get_prop_string(stream->ctx, -1, "unpipe"); // [stream][unpipe]
duk_swap_top(stream->ctx, -2); // [unpipe][this]
if (duk_pcall_method(stream->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
duk_pop(stream->ctx); // ...
}
duk_ret_t ILibDuktape_readableStream_pause(duk_context *ctx)
@@ -482,7 +493,7 @@ duk_ret_t ILibDuktape_readableStream_pause(duk_context *ctx)
int ILibDuktape_readableStream_resume_flush(ILibDuktape_readableStream *rs)
{
// Sanity check, and make sure there is a listener first, otherwise we're wasting our time
if (rs->OnData == NULL && rs->nextWriteable == NULL && rs->OnEnd == NULL)
if(ILibDuktape_EventEmitter_HasListeners(rs->emitter, "data")==0 && rs->nextWriteable == NULL && ILibDuktape_EventEmitter_HasListeners(rs->emitter, "end")==0)
{
return 1; // No listeners....
}
@@ -528,12 +539,23 @@ duk_ret_t ILibDuktape_readableStream_resume(duk_context *ctx)
void ILibDuktape_ReadableStream_pipe_ResumeLater(duk_context *ctx, void **args, int argsLen)
{
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)args[0];
rs->resumeImmediate = NULL;
if (ILibDuktape_readableStream_resume_flush(rs) == 0 && rs->ResumeHandler != NULL) { rs->paused = 0; rs->ResumeHandler(rs, rs->user); }
if (rs->PipeHookHandler != NULL) { rs->PipeHookHandler(rs, args[1], rs->user); }
}
void ILibDuktape_readableStream_pipe_later(duk_context *ctx, void **args, int argsLen)
{
duk_push_heapptr(ctx, args[0]); // [readable]
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS);
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx);
duk_push_heapptr(ctx, rs->pipeImmediate);
duk_del_prop_string(ctx, -1, "dest");
duk_pop(ctx);
rs->pipeImmediate = NULL;
duk_get_prop_string(ctx, -1, "pipe"); // [readable][pipe]
duk_swap_top(ctx, -2); // [pipe][this]
duk_push_heapptr(ctx, args[1]); // [pipe][this][writable]
@@ -557,8 +579,10 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
{
// We must YIELD and try again later, becuase there is an active dispatch going on
duk_push_this(ctx);
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
rstream->pipeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
duk_push_heapptr(ctx, rstream->pipeImmediate); // [immediate]
duk_dup(ctx, 0); // [immediate][ws]
duk_put_prop_string(ctx, -2, "dest"); // [immediate]
duk_dup(ctx, 0);
sem_post(&(rstream->pipeLock));
return(1);
@@ -615,12 +639,14 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
duk_push_string(ctx, "pipe"); // [emit][this][pipe]
duk_push_this(ctx); // [emit][this][pipe][readable]
duk_call_method(ctx, 2); duk_pop(ctx); // ...
if (rstream->paused != 0)
{
// We are paused, so we should yield and resume... We yield, so in case the user tries to chain multiple pipes, it will chain first
ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0) }, 1, ILibDuktape_ReadableStream_pipe_ResumeLater);
rstream->resumeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0) }, 1, ILibDuktape_ReadableStream_pipe_ResumeLater);
duk_push_heapptr(ctx, rstream->resumeImmediate); // [immediate]
duk_push_this(ctx); // [immediate][this]
duk_put_prop_string(ctx, -2, "self"); // [immediate]
duk_pop(ctx); // ...
}
else
{
@@ -646,7 +672,12 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
if (data->pipeInProgress != 0)
{
// We must yield, and try again, because there's an active dispatch going on
ILibDuktape_Immediate(ctx, (void*[]) { args[0], args[1] }, argsLen, ILibDuktape_readableStream_unpipe_later);
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { args[0], args[1] }, argsLen, ILibDuktape_readableStream_unpipe_later);
duk_push_heapptr(ctx, imm); // [immediate]
duk_push_heapptr(ctx, args[0]); // [immediate][this]
duk_put_prop_string(ctx, -2, "\xFF_Self"); // [immediate]
if (args[1] != NULL) { duk_push_heapptr(ctx, args[1]); duk_put_prop_string(ctx, -2, "\xFF_w"); }
duk_pop(ctx); // ...
sem_post(&(data->pipeLock));
return;
}
@@ -683,11 +714,11 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
for (i = 0; i < (int)arrayLen; ++i)
{
duk_get_prop_index(ctx, -1, i); // [array][ws]
ILibDuktape_Push_ObjectStash(ctx); // [array][ws][stash]
if (duk_has_prop_string(ctx, -1, Duktape_GetStashKey(args[1])))
if(duk_get_heapptr(ctx, -1) == args[1])
{
if (g_displayFinalizerMessages) { printf("*** UNPIPE/Removing Reference to Writeable: %s (RefCount: %d)\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1)); }
// Removing the entry from the Array
duk_pop_2(ctx); // [array]
duk_pop(ctx); // [array]
duk_get_prop_string(ctx, -1, "splice"); // [array][splice]
duk_swap_top(ctx, -2); // [splice][this]
duk_push_int(ctx, i); // [splice][this][i]
@@ -707,10 +738,10 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
else
{
// 'unpipe' all pipes
w = data->nextWriteable;
while (w != NULL)
{
duk_push_heapptr(ctx, w->writableStream); // [ws]
if (g_displayFinalizerMessages) { printf("*** UNPIPE/Removing Reference to Writeable: %s (RefCount: %d)\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1)); }
duk_get_prop_string(ctx, -1, "emit"); // [ws][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "unpipe"); // [emit][this][unpipe]
@@ -752,7 +783,13 @@ duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
duk_call_method(ctx, 0); duk_pop(ctx); // [readable]
// We must yield, and do this on the next event loop, because we can't unpipe if we're called from a pipe'ed call
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), nargs == 1 ? duk_get_heapptr(ctx, 0) : NULL }, nargs + 1, ILibDuktape_readableStream_unpipe_later);
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), nargs == 1 ? duk_get_heapptr(ctx, 0) : NULL }, nargs + 1, ILibDuktape_readableStream_unpipe_later);
duk_push_heapptr(ctx, imm); // [immediate]
duk_push_this(ctx); // [immediate][this]
duk_put_prop_string(ctx, -2, "\xFF_Self"); // [immediate]
if (nargs == 1) { duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, "\xFF_w"); }
duk_pop(ctx); // ...
return 0;
}
duk_ret_t ILibDuktape_readableStream_isPaused(duk_context *ctx)
@@ -777,13 +814,23 @@ duk_ret_t ILibDuktape_readableStream_pipe_getter(duk_context *ctx)
duk_push_c_function(ctx, ILibDuktape_readableStream_pipe, DUK_VARARGS);
return 1;
}
void ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx, void *stream)
duk_ret_t ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx)
{
ILibDuktape_readableStream_bufferedData *tmp;
ILibDuktape_readableStream *ptrs;
duk_push_heapptr(ctx, stream); // [stream]
duk_push_this(ctx); // [stream]
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS); // [stream][buffer]
ptrs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
if (ptrs->pipeImmediate != NULL)
{
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "clearImmediate"); // [g][clearImmediate]
duk_swap_top(ctx, -2); // [clearImmediate][this]
duk_push_heapptr(ctx, ptrs->pipeImmediate); // [clearImmediate][this][immedate]
duk_call_method(ctx, 1); duk_pop(ctx); // ...
ptrs->pipeImmediate = NULL;
}
while ((tmp = (ILibDuktape_readableStream_bufferedData*)ptrs->paused_data) != NULL)
{
@@ -794,6 +841,7 @@ void ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx, void *stream
sem_destroy(&(ptrs->pipeLock));
duk_pop_2(ctx);
return(0);
}
duk_ret_t ILibDuktape_ReadableStream_unshift(duk_context *ctx)
{
@@ -809,7 +857,7 @@ duk_ret_t ILibDuktape_ReadableStream_unshift(duk_context *ctx)
else
{
duk_size_t bufferLen;
Duktape_GetBuffer(ctx, 0, &bufferLen);
rs->unshiftReserved = (char*)Duktape_GetBuffer(ctx, 0, &bufferLen);
duk_push_int(ctx, rs->UnshiftHandler(rs, (int)bufferLen, rs->user));
return(1);
}
@@ -831,7 +879,6 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
retVal->pipeArray = duk_get_heapptr(ctx, -1);
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_PipeArray); // [obj]
retVal->ctx = ctx;
retVal->chain = Duktape_GetChain(ctx);
retVal->object = duk_get_heapptr(ctx, -1);
@@ -840,12 +887,12 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
retVal->ResumeHandler = OnResume;
retVal->UnshiftHandler = OnUnshift;
sem_init(&(retVal->pipeLock), 0, 1);
ILibDuktape_CreateIndependentFinalizer(ctx, ILibDuktape_ReadableStream_PipeLockFinalizer);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ReadableStream_PipeLockFinalizer);
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEvent(emitter, "end", &(retVal->OnEnd));
ILibDuktape_EventEmitter_CreateEvent(emitter, "data", &(retVal->OnData));
ILibDuktape_EventEmitter_CreateEvent(emitter, "close", &(retVal->OnClose));
retVal->emitter = emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "end");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "data");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "close");
ILibDuktape_CreateInstanceMethod(ctx, "pause", ILibDuktape_readableStream_pause, 0);
ILibDuktape_CreateInstanceMethod(ctx, "resume", ILibDuktape_readableStream_resume, 0);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ limitations under the License.
#include "duktape.h"
#include "microstack/ILibParsers.h"
#include "ILibDuktape_EventEmitter.h"
#define ILibDuktape_readableStream_RSPTRS "\xFF_ReadableStream_PTRS"
@@ -39,9 +40,6 @@ typedef struct ILibDuktape_readableStream
duk_context *ctx;
void *chain;
void *object;
void *OnClose;
void *OnData;
void *OnEnd;
void *user;
void *pipeArray;
@@ -64,6 +62,10 @@ typedef struct ILibDuktape_readableStream
ILibDuktape_readableStream_PauseResumeHandler ResumeHandler;
ILibDuktape_readableStream_MethodHookHandler PipeHookHandler;
ILibDuktape_readableStream_UnShiftHandler UnshiftHandler;
ILibDuktape_EventEmitter *emitter;
char *unshiftReserved;
void *resumeImmediate;
void *pipeImmediate;
}ILibDuktape_readableStream;
ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx, ILibDuktape_readableStream_PauseResumeHandler OnPause, ILibDuktape_readableStream_PauseResumeHandler OnResume, ILibDuktape_readableStream_UnShiftHandler OnUnshift, void *user);
@@ -71,6 +73,7 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
#define ILibDuktape_ReadableStream_Init(ctx, OnPause, OnResume, user) ILibDuktape_ReadableStream_InitEx(ctx, OnPause, OnResume, NULL, user)
#define ILibDuktape_readableStream_SetPauseResumeHandlers(stream, PauseFunc, ResumeFunc, userObj) ((ILibDuktape_readableStream*)stream)->PauseHandler = PauseFunc; ((ILibDuktape_readableStream*)stream)->ResumeHandler = ResumeFunc; ((ILibDuktape_readableStream*)stream)->user = userObj;
void ILibDuktape_ReadableStream_DestroyPausedData(ILibDuktape_readableStream *stream);
int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, int streamReserved, char* buffer, int bufferLen);
int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream);
#define ILibDuktape_readableStream_WriteData(stream, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx(stream, 0, buffer, bufferLen)

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "ILibDuktape_SHA256.h"
#include "duktape.h"
#include "ILibDuktape_Helpers.h"
@@ -21,8 +37,6 @@ typedef struct ILibDuktape_SHA256_Data
duk_context *ctx;
void *object;
void *OnHash;
void *OnHashString;
char buffer[33];
SHA256_CTX shctx;
}ILibDuktape_SHA256_Data;
@@ -31,8 +45,6 @@ typedef struct ILibDuktape_SHA512_Data
duk_context *ctx;
void *object;
void *OnHash;
void *OnHashString;
char buffer[65];
SHA512_CTX shctx;
}ILibDuktape_SHA512_Data;
@@ -41,8 +53,6 @@ typedef struct ILibDuktape_MD5_Data
duk_context *ctx;
void *object;
void *OnHash;
void *OnHashString;
char buffer[33];
MD5_CTX mctx;
}ILibDuktape_MD5_Data;
@@ -82,34 +92,21 @@ ILibTransport_DoneState ILibDuktape_SHA384_Write(struct ILibDuktape_WritableStre
}
void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA256_Data *data = (ILibDuktape_SHA256_Data*)user;
data->buffer[32] = 0;
SHA256_Final((unsigned char*)data->buffer, &(data->shctx));
if (data->ctx != NULL && data->OnHash != NULL)
{
duk_push_heapptr(data->ctx, data->OnHash); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_external_buffer(data->ctx); // [func][this][hash]
duk_config_buffer(data->ctx, -1, data->buffer, 32);
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
if (data->ctx != NULL && data->OnHashString != NULL)
{
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [func][this][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, 32);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop_2(data->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hash']
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]['hash'][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // ...
}
void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *user)
{
@@ -117,29 +114,17 @@ void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *use
data->buffer[48] = 0;
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
if (data->ctx != NULL && data->OnHash != NULL)
{
duk_push_heapptr(data->ctx, data->OnHash); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_external_buffer(data->ctx); // [func][this][hash]
duk_config_buffer(data->ctx, -1, data->buffer, 48);
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
if (data->ctx != NULL && data->OnHashString != NULL)
{
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [func][this][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, 48);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
duk_push_buffer_object(data->ctx, -4, 0, 48, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop_2(data->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hashString']
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [emit][this]['hashString'][hashString]
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // ...
}
duk_ret_t ILibDuktape_SHA256_SIGNER_Finalizer(duk_context *ctx)
{
@@ -175,7 +160,7 @@ void ILibDuktape_SHA256_SIGNER_End(struct ILibDuktape_WritableStream *stream, vo
duk_swap_top(data->ctx, -2); // [sigBuffer][signer]
duk_push_heapptr(data->ctx, data->OnSignature); // [sigBuffer][signer][func]
duk_swap_top(data->ctx, -2); // [sigBuffer][func][signer/this]
duk_push_buffer_object(data->ctx, -3, 0, len, DUK_BUFOBJ_DUKTAPE_BUFFER); // [sigBuffer][func][signer/this][bufView]
duk_push_buffer_object(data->ctx, -3, 0, len, DUK_BUFOBJ_NODEJS_BUFFER); // [sigBuffer][func][signer/this][bufView]
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); } // ...
}
duk_pop(data->ctx); // ...
@@ -363,29 +348,23 @@ void ILibDuktape_MD5_End(struct ILibDuktape_WritableStream *stream, void *user)
data->buffer[32] = 0;
MD5_Final((unsigned char*)data->buffer, &(data->mctx));
if (data->ctx != NULL && data->OnHash != NULL)
duk_push_external_buffer(data->ctx); // [extBuffer]
duk_config_buffer(data->ctx, -1, data->buffer, 32);
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
{
duk_push_heapptr(data->ctx, data->OnHash); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_external_buffer(data->ctx); // [func][this][hash]
duk_config_buffer(data->ctx, -1, data->buffer, 32);
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
ILibDuktape_Process_UncaughtException(data->ctx);
}
if (data->ctx != NULL && data->OnHashString != NULL)
duk_pop_2(data->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]["hashString"]
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]["hashString"][hashString]
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
{
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [func][this][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
duk_ret_t ILibDuktape_MD5_syncHash(duk_context *ctx)
{
@@ -431,8 +410,8 @@ duk_ret_t ILibDuktape_MD5_Create(duk_context *ctx)
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_MD5_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_MD5_syncHash, 1);
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
@@ -457,8 +436,8 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA256_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA256_syncHash, 1);
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
@@ -474,6 +453,7 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [sha]
ILibDuktape_WriteID(ctx, "SHA384Stream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA512_Data)); // [sha][buffer]
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SHA512_PTR); // [sha]
@@ -484,8 +464,8 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef ___DUKTAPE_SHA256___
#define ___DUKTAPE_SHA256___

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#ifdef WIN32
#include <WinSock2.h>
#include <ws2tcpip.h>
@@ -52,6 +51,7 @@ limitations under the License.
#include "ILibDuktape_Polyfills.h"
#include "ILibDuktape_SimpleDataStore.h"
#include "ILibDuktape_NetworkMonitor.h"
#include "ILibDuktape_ReadableStream.h"
#include "ILibDuktape_SHA256.h"
#include "ILibDuktape_EncryptionStream.h"
@@ -62,13 +62,16 @@ limitations under the License.
extern char **environ;
#endif
#define SCRIPT_ENGINE_PIPE_BUFFER_SIZE 65535
char exeJavaScriptGuid[] = "B996015880544A19B7F7E9BE44914C18";
#define ILibDuktape_ScriptContainer_MasterPtr "\xFF_ScriptContainer_MasterPtr"
#define ILibDuktape_ScriptContainer_SlavePtr "\xFF_ScriptContainer_SlavePtr"
#define ILibDuktape_ScriptContainer_ExePath "\xFF_ScriptContainer_ExePath"
#define ILibDuktape_ScriptContainer_PipeManager "\xFF_ScriptContainer_PipeManager"
#define ILibDuktape_ScriptContainer_PtrTable "\xFF_ScriptContainer_PtrTable"
#define ILibDuktape_ScriptContainer_PtrTable_Idx "\xFF_ScriptContainer_PtrTableIdx"
#define ILibDuktape_ScriptContainer_ProcessIsolated "\xFF_ScriptContainer_ProcessIsolated"
#define ILibDuktape_ScriptContainer_PeerThread "\xFF_ScriptContainer_PeerThread"
#define ILibDuktape_ScriptContainer_Command_Execute_Status "ScriptContainer_Command_Execute_Status"
#define ILibDuktape_ScriptContainer_Command_Log "ScriptContainer_Command_Log"
@@ -79,6 +82,7 @@ extern char **environ;
#define ILibDuktape_ScriptContainer_Settings_ExitUser "\xFF_ScriptContainerSettings_ExitUser"
#define ILibDuktape_ScriptContainer_Process_ArgArray "\xFF_argArray"
#define ILibDuktape_ScriptContainer_Process_Restart "\xFF_ScriptContainer_Process_Restart"
#define ILibDuktape_ScriptContainer_Process_stdin "\xFF_stdin"
#define ILibDuktape_ScriptContainer_ExitCode "\xFF_ExitCode"
#define ILibDuktape_ScriptContainer_Exitting "\xFF_Exiting"
@@ -111,6 +115,7 @@ extern char **environ;
extern void ILibDuktape_MemoryStream_Init(duk_context *ctx);
extern void ILibDuktape_NetworkMonitor_Init(duk_context *ctx);
char g_AgentCrashID[280];
typedef enum SCRIPT_ENGINE_COMMAND
{
@@ -121,6 +126,8 @@ typedef enum SCRIPT_ENGINE_COMMAND
SCRIPT_ENGINE_COMMAND_SEND_JSON = 0x10,
SCRIPT_ENGINE_COMMAND_QUERY = 0x20,
SCRIPT_ENGINE_COMMAND_SET = 0x21,
SCRIPT_ENGINE_COMMAND_ERROR = 0x40,
SCRIPT_ENGINE_COMMAND_EXIT = 0x80,
SCRIPT_ENGINE_COMMAND_LOG = 0xFF
}SCRIPT_ENGINE_COMMAND;
@@ -132,7 +139,8 @@ typedef struct ILibDuktape_ScriptContainer_Master
ILibProcessPipe_Process child;
void *chain;
void *OnExit, *OnError, *OnJSON;
void *PeerThread, *PeerChain;
unsigned int ChildSecurityFlags;
}ILibDuktape_ScriptContainer_Master;
typedef struct ILibDuktape_ScriptContainer_Slave
@@ -140,11 +148,21 @@ typedef struct ILibDuktape_ScriptContainer_Slave
duk_context *ctx;
ILibDuktape_EventEmitter *emitter;
void *OnData;
void *chain;
int exitCode;
int noRespond;
}ILibDuktape_ScriptContainer_Slave;
typedef struct ILibDuktape_ScriptContainer_NonIsolated_Command
{
union { ILibDuktape_ScriptContainer_Master * master; ILibDuktape_ScriptContainer_Slave *slave; }container;
char json[];
}ILibDuktape_ScriptContainer_NonIsolated_Command;
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave(void *chain, void *user);
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster(void *chain, void *user);
#ifdef _REMOTELOGGING
void ILibDuktape_ScriptContainer_Slave_LogForwarder(ILibRemoteLogging sender, ILibRemoteLogging_Modules module, ILibRemoteLogging_Flags flags, char *buffer, int bufferLen)
{
@@ -190,40 +208,134 @@ void ILibDuktape_ScriptContainer_Slave_OnBrokenPipe(ILibProcessPipe_Pipe sender)
void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *scriptLen)
{
// Check if .JS file is integrated with executable
int i;
FILE *tmpFile;
char *integratedJavaScript = NULL;
int integratedJavaScriptLen = 0;
#ifdef WIN32
if (ILibString_EndsWith(argv[0], -1, ".exe", 4) == 0)
{
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s_", argv[0]);
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", argv[0]);
fopen_s(&tmpFile, ILibScratchPad, "rb");
}
else
{
i = ILibString_LastIndexOf(argv[0], -1, "\\", 1);
if (i > 0)
{
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s", argv[0] + i + 1);
g_AgentCrashID[i-4] = '_';
i -= 3;
}
else
{
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s", argv[0]);
g_AgentCrashID[i-4] = '_';
i -= 3;
}
fopen_s(&tmpFile, argv[0], "rb");
}
#else
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s_", argv[0]);
tmpFile = fopen(argv[0], "rb");
#endif
if (tmpFile != NULL)
{
fseek(tmpFile, 0, SEEK_END);
fseek(tmpFile, ftell(tmpFile) - 4, SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 4, tmpFile));
fseek(tmpFile, 0, SEEK_END);
if (ftell(tmpFile) == ntohl(((int*)ILibScratchPad)[0]))
SHA512_CTX shctx;
char hashBuffer[4096];
char hashValue[1 + UTIL_SHA384_HASHSIZE];
int hashBufferReadLen;
SHA384_Init(&shctx);
while ((hashBufferReadLen = (int)fread(hashBuffer, 1, sizeof(hashBuffer), tmpFile)) > 0)
{
fseek(tmpFile, ftell(tmpFile) - 8, SEEK_SET);
SHA384_Update(&shctx, hashBuffer, hashBufferReadLen);
}
SHA384_Final((unsigned char*)hashValue, &shctx);
util_tohex(hashValue, UTIL_SHA384_HASHSIZE, g_AgentCrashID + i);
#ifdef WIN32
memcpy_s(g_AgentCrashID + i + 16, 5, ".exe", 5);
#else
g_AgentCrashID[i + 16] = 0;
#endif
g_ILibCrashID = g_AgentCrashID;
#ifdef WIN32
// Read the PE Headers, to determine where to look for the Embedded JS
char *optHeader = NULL;
fseek(tmpFile, 0, SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 2, tmpFile));
if (ntohs(((unsigned int*)ILibScratchPad)[0]) == 19802) // 5A4D
{
fseek(tmpFile, 60, SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 4, tmpFile));
integratedJavaScriptLen = ntohl(((int*)ILibScratchPad)[0]);
integratedJavaScript = ILibMemory_Allocate(1 + integratedJavaScriptLen, 0, NULL, NULL);
fseek(tmpFile, 0, SEEK_END);
fseek(tmpFile, ftell(tmpFile) - 8 - integratedJavaScriptLen, SEEK_SET);
fseek(tmpFile, ((unsigned *)ILibScratchPad)[0], SEEK_SET);
ignore_result(fread(ILibScratchPad, 1, 24, tmpFile));
if (((unsigned int*)ILibScratchPad)[0] == 17744)
{
// PE Image
optHeader = ILibMemory_AllocateA(((unsigned short*)ILibScratchPad)[10]);
ignore_result(fread(optHeader, 1, ILibMemory_AllocateA_Size(optHeader), tmpFile));
switch (((unsigned short*)optHeader)[0])
{
case 0x10B:
if (((unsigned int*)(optHeader + 128))[0] != 0)
{
fseek(tmpFile, ((unsigned int*)(optHeader + 128))[0] - 16, SEEK_SET);
}
else
{
fseek(tmpFile, -16, SEEK_END);
}
break;
case 0x20B:
if (((unsigned int*)(optHeader + 144))[0] != 0)
{
fseek(tmpFile, ((unsigned int*)(optHeader + 144))[0] - 16, SEEK_SET);
}
else
{
fseek(tmpFile, -16, SEEK_END);
}
break;
default:
fclose(tmpFile);
return;
}
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
util_hexToBuf(exeJavaScriptGuid, 32, ILibScratchPad2);
if (memcmp(ILibScratchPad, ILibScratchPad2, 16) == 0)
{
// Found an Embedded JS
fseek(tmpFile, -20, SEEK_CUR);
ignore_result(fread((void*)&integratedJavaScriptLen, 1, 4, tmpFile));
integratedJavaScriptLen = (int)ntohl(integratedJavaScriptLen);
fseek(tmpFile, -4 - integratedJavaScriptLen, SEEK_CUR);
integratedJavaScript = ILibMemory_Allocate(integratedJavaScriptLen + 1, 0, NULL, NULL);
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
integratedJavaScript[integratedJavaScriptLen] = 0;
}
}
}
#else
fseek(tmpFile, -16, SEEK_END);
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
util_hexToBuf(exeJavaScriptGuid, 32, ILibScratchPad2);
if (memcmp(ILibScratchPad, ILibScratchPad2, 16) == 0)
{
// Found an Embedded JS
fseek(tmpFile, -20, SEEK_CUR);
ignore_result(fread((void*)&integratedJavaScriptLen, 1, 4, tmpFile));
integratedJavaScriptLen = (int)ntohl(integratedJavaScriptLen);
fseek(tmpFile, -4 - integratedJavaScriptLen, SEEK_CUR);
integratedJavaScript = ILibMemory_Allocate(integratedJavaScriptLen + 1, 0, NULL, NULL);
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
integratedJavaScript[integratedJavaScriptLen] = 0;
}
#endif
fclose(tmpFile);
}
*script = integratedJavaScript;
@@ -353,6 +465,146 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_env(duk_context *ctx)
return(1);
}
duk_ret_t ILibDuktape_ScriptContainer_Process_Finalizer(duk_context *ctx)
{
// We need to dispatch the 'exit' event
int exitCode = 0;
duk_push_this(ctx); // [process]
if (duk_has_prop_string(ctx, -1, "\xFF_ExitCode"))
{
duk_get_prop_string(ctx, -1, "\xFF_ExitCode"); // [process][exitCode]
exitCode = duk_get_int(ctx, -1);
duk_pop(ctx); // [process]
}
ILibDuktape_EventEmitter_SetupEmit(ctx, duk_get_heapptr(ctx, -1), "exit"); // [emit][this]['exit']
duk_push_int(ctx, exitCode); // [emit][this]['exit'][exitCode]
duk_call_method(ctx, 2);
return(0);
}
typedef struct ILibDuktape_Process_StdIn_Data
{
ILibDuktape_readableStream *rs;
#ifdef WIN32
HANDLE workerThread;
HANDLE resumeEvent;
int exit;
#endif
int wasUnshifted;
int endPointer;
int bufferSize;
char buffer[];
}ILibDuktape_Process_StdIn_Data;
#ifdef WIN32
void __stdcall ILibDuktape_Process_stdin_readSink(ULONG_PTR obj)
{
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)obj;
int endPointer;
do
{
endPointer = data->endPointer;
data->wasUnshifted = 0;
ILibDuktape_readableStream_WriteData(data->rs, data->buffer, data->endPointer);
} while (!data->rs->paused && data->wasUnshifted > 0 && data->wasUnshifted != endPointer);
data->endPointer = data->wasUnshifted;
if (!data->rs->paused) { SetEvent(data->resumeEvent); }
}
#endif
void ILibDuktape_Process_stdin_pauseSink(struct ILibDuktape_readableStream *sender, void *user)
{
UNREFERENCED_PARAMETER(sender);
UNREFERENCED_PARAMETER(user);
// NO-OP, because stream state flag will be paused, which will cause the processing loop to exit
}
void ILibDuktape_Process_stdin_resumeSink(struct ILibDuktape_readableStream *sender, void *user)
{
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)user;
#ifdef WIN32
SetEvent(data->resumeEvent);
#endif
}
int ILibDuktape_Process_stdin_unshiftSink(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user)
{
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)user;
data->wasUnshifted = unshiftBytes <= data->endPointer ? unshiftBytes : data->endPointer;
if (unshiftBytes > 0 && unshiftBytes < data->endPointer)
{
memmove_s(data->buffer, data->bufferSize, data->buffer + (data->endPointer - unshiftBytes), unshiftBytes);
data->endPointer = unshiftBytes;
}
return(data->wasUnshifted);
}
#ifdef WIN32
void ILibDuktape_Process_stdin_WindowsRunLoop(void *arg)
{
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)arg;
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
DWORD bytesRead, waitResult;
while (((waitResult = WaitForSingleObjectEx(data->resumeEvent, INFINITE, TRUE)) == WAIT_OBJECT_0 || waitResult == WAIT_IO_COMPLETION) && !data->exit)
{
if (!ReadFile(h, data->buffer + data->endPointer, data->bufferSize - data->endPointer, &bytesRead, NULL))
{
break;
}
else
{
ResetEvent(data->resumeEvent); // Reset, becuase we'll need to pause and context switch to Duktape thread
data->endPointer += (int)bytesRead;
QueueUserAPC((PAPCFUNC)ILibDuktape_Process_stdin_readSink, ILibChain_GetMicrostackThreadHandle(data->rs->chain), (ULONG_PTR)data);
}
}
}
#endif
duk_ret_t ILibDuktape_Process_stdin_finalizer(duk_context *ctx)
{
duk_get_prop_string(ctx, 0, ILibDuktape_readableStream_RSPTRS);
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)rs->user;
#ifdef WIN32
data->exit = 1;
SetEvent(data->resumeEvent);
CancelSynchronousIo(data->workerThread);
WaitForSingleObject(data->workerThread, 10000);
CloseHandle(data->resumeEvent);
#endif
free(data);
return(0);
}
duk_ret_t ILibDuktape_Process_stdin_get(duk_context *ctx)
{
duk_push_this(ctx); // [process]
if (duk_has_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_stdin))
{
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_stdin);
return(1);
}
duk_push_object(ctx); // [process][stdin]
duk_dup(ctx, -1); // [process][stdin][dup]
duk_put_prop_string(ctx, -3, ILibDuktape_ScriptContainer_Process_stdin); // [process][stdin]
ILibDuktape_WriteID(ctx, "process.stdin");
ILibDuktape_readableStream *rs = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_Process_stdin_pauseSink, ILibDuktape_Process_stdin_resumeSink, ILibDuktape_Process_stdin_unshiftSink, NULL);
rs->user = ILibMemory_Allocate(sizeof(ILibDuktape_Process_StdIn_Data) + 4096, 0, NULL, NULL);
((ILibDuktape_Process_StdIn_Data*)rs->user)->rs = rs;
((ILibDuktape_Process_StdIn_Data*)rs->user)->bufferSize = 4096;
#ifdef WIN32
((ILibDuktape_Process_StdIn_Data*)rs->user)->resumeEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
((ILibDuktape_Process_StdIn_Data*)rs->user)->workerThread = ILibSpawnNormalThread(ILibDuktape_Process_stdin_WindowsRunLoop, rs->user);
#endif
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_Process_stdin_finalizer);
return(1);
}
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
{
int i = 0;
@@ -360,6 +612,7 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
duk_push_global_object(ctx); // [g]
duk_push_object(ctx); // [g][process]
ILibDuktape_WriteID(ctx, "process");
ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
#if defined(WIN32) // [g][process][platform]
@@ -416,8 +669,21 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
duk_push_int(ctx, 0);
ILibDuktape_CreateEventWithGetterAndCustomProperty(ctx, "readOnly", "_argv", ILibDuktape_ScriptContainer_Process_Argv);
duk_push_heap_stash(ctx); // [g][process][stash]
if (!duk_has_prop_string(ctx, -1, ILibDuktape_ScriptContainer_SlavePtr))
{
duk_pop(ctx); // [g][process]
ILibDuktape_CreateEventWithGetter(ctx, "stdin", ILibDuktape_Process_stdin_get);
}
else
{
duk_pop(ctx); // [g][process]
}
duk_put_prop_string(ctx, -2, "process"); // [g]
duk_pop(ctx); // ...
ILibDuktape_EventEmitter_AddOnceEx(emitter, "~", ILibDuktape_ScriptContainer_Process_Finalizer, 1);
}
void ILibDuktape_ScriptContainer_ExecTimeout_Finalizer(duk_context *ctx, void *timeoutKey)
{
@@ -510,9 +776,9 @@ void ILibDuktape_ScriptContainer_Engine_free(void *udata, void *ptr)
{
free(ptr);
}
void ILibDuktape_ScriptContainer_Engine_fatal(duk_context *ctx, duk_errcode_t code, const char *msg)
void ILibDuktape_ScriptContainer_Engine_fatal(void *udata, const char *msg)
{
ILIBCRITICALEXITMSG(code, msg);
ILIBCRITICALEXITMSG(254, msg);
}
duk_ret_t ILibDuktape_ScriptContainer_OS_arch(duk_context *ctx)
{
@@ -756,6 +1022,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [os]
ILibDuktape_WriteID(ctx, "os");
#ifdef WIN32
duk_push_string(ctx, "\r\n");
@@ -773,10 +1040,13 @@ void ILibDuktape_ScriptContainer_OS_Init(duk_context *ctx)
ILibDuktape_ModSearch_AddHandler(ctx, "os", ILibDuktape_ScriptContainer_OS_Push);
}
extern void ILibDuktape_HttpStream_Init(duk_context *ctx);
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser)
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal()
{
duk_context *ctx = duk_create_heap(ILibDuktape_ScriptContainer_Engine_malloc, ILibDuktape_ScriptContainer_Engine_realloc, ILibDuktape_ScriptContainer_Engine_free, NULL, ILibDuktape_ScriptContainer_Engine_fatal);
//duk_context *ctx = duk_create_heap_default();
return(ctx);
}
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_context *ctx, SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser)
{
void **timeoutKey = executionTimeout > 0 ? (void**)ILibMemory_Allocate(sizeof(void*), 0, NULL, NULL) : NULL;
duk_push_heap_stash(ctx); // [s]
@@ -897,7 +1167,7 @@ int ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(duk_context *ctx, cha
if (path == NULL || pathLen == 0)
{
duk_push_error_object(ctx, DUK_ERR_API_ERROR, "Invalid Path specified");
duk_push_error_object(ctx, DUK_ERR_ERROR, "Invalid Path specified");
return(1);
}
else
@@ -1153,16 +1423,15 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
break;
case SCRIPT_ENGINE_COMMAND_SEND_JSON:
{
if (slave->OnData != NULL)
if (ILibDuktape_EventEmitter_HasListeners(slave->emitter, "data")!=0)
{
char *json = Duktape_GetStringPropertyValue(slave->ctx, -1, "json", NULL);
if (json != NULL)
{
duk_push_heapptr(slave->ctx, slave->OnData); // [func]
duk_push_heapptr(slave->ctx, slave->emitter->object); // [func][this]
duk_push_string(slave->ctx, json); // [func][this][json]
duk_json_decode(slave->ctx, -1); // [func][this][object]
if (duk_pcall_method(slave->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(slave->ctx, "ScriptContainer.OnData(): "); }
ILibDuktape_EventEmitter_SetupEmit(slave->ctx, slave->emitter->object, "data"); // [emit][this][data]
duk_push_string(slave->ctx, json); // [emit][this][data][json]
duk_json_decode(slave->ctx, -1); // [emit][this][data][object]
if (duk_pcall_method(slave->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(slave->ctx, "ScriptContainer.OnData(): "); }
duk_pop(slave->ctx); // ...
}
}
@@ -1313,6 +1582,15 @@ duk_ret_t ILibDuktape_ScriptContainer_Exit(duk_context *ctx)
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_MasterPtr);
master = (ILibDuktape_ScriptContainer_Master*)Duktape_GetBuffer(ctx, -1, NULL);
if (master->PeerChain != NULL)
{
char json[] = "{\"command\": \"128\"}";
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
cmd->container.slave = ((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
memcpy_s(cmd->json, sizeof(json), json, sizeof(json));
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
return(0);
}
if (ILibIsChainBeingDestroyed(Duktape_GetChain(ctx)) == 0)
{
@@ -1338,6 +1616,27 @@ duk_ret_t ILibDuktape_ScriptContainer_ExecuteString(duk_context *ctx)
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_MasterPtr); // [container][buffer]
master = (ILibDuktape_ScriptContainer_Master*)Duktape_GetBuffer(ctx, -1, NULL); // [container][buffer]
if (master->PeerChain != NULL)
{
char json[] = "{\"command\": \"2\", \"base64\": \"\"}";
char *payload;
duk_size_t payloadLen;
payload = (char*)duk_get_lstring(ctx, 0, &payloadLen);
int encodedPayloadLen = ILibBase64EncodeLength((int)payloadLen);
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command) + encodedPayloadLen + sizeof(json), 0, NULL, NULL);
cmd->container.slave = (ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
int i = sprintf_s(cmd->json, sizeof(json) + encodedPayloadLen, json);
char *output = cmd->json + i -2;
i += ILibBase64Encode((unsigned char*)payload, (int)payloadLen, (unsigned char**)&output);
sprintf_s(cmd->json + i - 2, 3, "\"}");
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
return(0);
}
if (ptr != NULL) { seq = ILibDuktape_ScriptContainer_AddVoidPtr(ctx, duk_get_heapptr(ctx, -2), ptr); }
duk_push_object(ctx); // [container][buffer][obj]
@@ -1364,18 +1663,13 @@ duk_ret_t ILibDuktape_ScriptContainer_ExecuteString(duk_context *ctx)
void ILibDuktape_ScriptContainer_ExitSink(ILibProcessPipe_Process sender, int exitCode, void* user)
{
ILibDuktape_ScriptContainer_Master *master = (ILibDuktape_ScriptContainer_Master*)user;
if (master->OnExit != NULL)
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "exit"); // [emit][this][exit]
duk_push_int(master->ctx, exitCode); // [emit][this][exit][code]
if (duk_pcall_method(master->ctx, 2) != 0)
{
duk_push_heapptr(master->ctx, master->OnExit); // [func]
duk_push_heapptr(master->ctx, master->emitter->object); // [func][this]
duk_push_int(master->ctx, exitCode); // [func][this][code]
if (duk_pcall_method(master->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(master->ctx);
}
duk_pop(master->ctx); // ...
ILibDuktape_Process_UncaughtException(master->ctx);
}
duk_pop(master->ctx);
master->child = NULL;
}
@@ -1402,16 +1696,15 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
{
case SCRIPT_ENGINE_COMMAND_SEND_JSON:
{
if (master->OnJSON != NULL)
{
if(ILibDuktape_EventEmitter_HasListeners(master->emitter, "data")!=0)
{
char *json = Duktape_GetStringPropertyValue(master->ctx, -1, "json", NULL);
if (json != NULL)
{
duk_push_heapptr(master->ctx, master->OnJSON);
duk_push_heapptr(master->ctx, master->emitter->object);
duk_push_string(master->ctx, json);
duk_json_decode(master->ctx, -1);
if (duk_pcall_method(master->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer.OnData(): "); }
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "data"); // [emit][this][data]
duk_push_string(master->ctx, json); // [emit][this][data][str]
duk_json_decode(master->ctx, -1); // [emit][this][data][json]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer.OnData(): "); }
duk_pop(master->ctx);
}
}
@@ -1430,14 +1723,10 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
if ((i = Duktape_GetIntPropertyValue(master->ctx, -1, "sequence", -1)) < 0)
{
// No callback was specified
if (master->OnError != NULL)
{
duk_push_heapptr(master->ctx, master->OnError); // [func]
duk_push_heapptr(master->ctx, master->emitter->object); // [func][this]
duk_get_prop_string(master->ctx, -3, "error"); // [func][this][error]
if (duk_pcall_method(master->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
duk_pop(master->ctx); // ...
}
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "error"); // [emit][this][error]
duk_get_prop_string(master->ctx, -4, "error"); // [emit][this][error][errorObj]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
duk_pop(master->ctx); // ...
}
else
{
@@ -1515,6 +1804,17 @@ duk_ret_t ILibDuktape_ScriptContainer_Finalizer(duk_context *ctx)
{
ILibProcessPipe_Process_KillEx(master->child);
}
else if (master->PeerChain != NULL)
{
char json[] = "{\"command\": \"128\", \"noResponse\": \"1\"}";
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
cmd->container.slave = ((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
memcpy_s(cmd->json, sizeof(json), json, sizeof(json));
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
#ifdef WIN32
WaitForSingleObject(master->PeerThread, INFINITE);
#endif
}
return(0);
}
@@ -1535,10 +1835,23 @@ duk_ret_t ILibDuktape_ScriptContainer_SendToSlave(duk_context *ctx)
duk_put_prop_string(ctx, -2, "json"); // [container][master][obj]
duk_json_encode(ctx, -1); // [container][master][json]
len = sprintf_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, "%s", duk_get_string(ctx, -1));
((int*)ILibScratchPad2)[0] = len + 4;
ILibProcessPipe_Process_WriteStdIn(master->child, ILibScratchPad2, len + 4, ILibTransport_MemoryOwnership_USER);
if (master->child != NULL)
{
len = sprintf_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, "%s", duk_get_string(ctx, -1));
((int*)ILibScratchPad2)[0] = len + 4;
ILibProcessPipe_Process_WriteStdIn(master->child, ILibScratchPad2, len + 4, ILibTransport_MemoryOwnership_USER);
}
else if(master->PeerChain != NULL)
{
duk_size_t payloadLen;
char *payload = (char*)duk_get_lstring(ctx, -1, &payloadLen);
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = ILibMemory_Allocate(sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command) + (int)payloadLen + 1, 0, NULL, NULL);
cmd->container.slave = (ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
memcpy_s(cmd->json, payloadLen + 1, payload, payloadLen + 1);
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
}
return(0);
}
duk_ret_t ILibDuktape_ScriptContainer_Master_AddModule(duk_context *ctx)
@@ -1565,6 +1878,181 @@ duk_ret_t ILibDuktape_ScriptContainer_Master_AddModule(duk_context *ctx)
ILibProcessPipe_Process_WriteStdIn(master->child, ILibScratchPad2, len+4, ILibTransport_MemoryOwnership_USER);
return(0);
}
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster(void *chain, void *user)
{
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)user;
ILibDuktape_ScriptContainer_Master *master = cmd->container.master;
ILibDuktape_ScriptContainer_Slave *slave = master->PeerChain == NULL ? NULL : (ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
int id;
duk_push_string(master->ctx, cmd->json); // [string]
duk_json_decode(master->ctx, -1); // [json]
free(cmd);
switch ((id = Duktape_GetIntPropertyValue(master->ctx, -1, "command", -1)))
{
case 0: // Ready
{
// Call INIT first
char json[] = "{\"command\": \"1\"}";
ILibDuktape_ScriptContainer_NonIsolated_Command* initCmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
initCmd->container.slave = slave;
memcpy_s(initCmd->json, sizeof(json), json, sizeof(json));
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, initCmd);
// Emit Ready Event
duk_push_heapptr(master->ctx, master->emitter->object); // [json][container]
duk_get_prop_string(master->ctx, -1, "emit"); // [json][container][emit]
duk_swap_top(master->ctx, -2); // [json][emit][this]
duk_push_string(master->ctx, "ready"); // [json][emit][this][ready]
if (duk_pcall_method(master->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Error Dispatching 'ready' event to Master Script Container"); }
duk_pop(master->ctx); // [json]
}
break;
case SCRIPT_ENGINE_COMMAND_ERROR:
duk_push_heapptr(master->ctx, master->emitter->object); // [json][container]
duk_get_prop_string(master->ctx, -1, "emit"); // [json][container][emit]
duk_swap_top(master->ctx, -2); // [json][emit][this]
duk_push_string(master->ctx, "error"); // [json][emit][this][error]
duk_get_prop_string(master->ctx, -4, "message"); // [json][emit][this][error][msg]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Error Emitting ScriptContainer Error Message: "); }
duk_pop(master->ctx); // [json]
break;
case SCRIPT_ENGINE_COMMAND_EXIT:
duk_push_heapptr(master->ctx, master->emitter->object); // [json][container]
duk_get_prop_string(master->ctx, -1, "emit"); // [json][container][emit]
duk_swap_top(master->ctx, -2); // [json][emit][this]
duk_push_string(master->ctx, "exit"); // [json][emit][this][exit]
duk_get_prop_string(master->ctx, -4, "exitCode"); // [json][emit][this][exit][msg]
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Error Emitting ScriptContainer Exit: "); }
duk_pop(master->ctx); // [json]
master->PeerChain = NULL;
break;
default:
ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Unknown Command [%d] Received from Slave Container ", id);
break;
}
duk_pop(master->ctx); // ...
}
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ExceptionSink(duk_context *ctx, char *msg, void *user)
{
duk_push_object(ctx); // [obj]
duk_push_int(ctx, (int)SCRIPT_ENGINE_COMMAND_ERROR);
duk_put_prop_string(ctx, -2, "command");
duk_push_string(ctx, msg);
duk_put_prop_string(ctx, -2, "message");
duk_json_encode(ctx, -1); // [json]
duk_size_t payloadLen;
char *payload = (char*)duk_get_lstring(ctx, -1, &payloadLen);
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate((int)(sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command) + payloadLen + 1), 0, NULL, NULL);
cmd->container.master = ((void**)ILibMemory_GetExtraMemory(Duktape_GetChain(ctx), ILibMemory_CHAIN_CONTAINERSIZE))[0];
memcpy_s(cmd->json, payloadLen + 1, payload, payloadLen + 1);
duk_pop(ctx); // ...
ILibChain_RunOnMicrostackThread(cmd->container.master->chain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster, cmd);
}
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave(void *chain, void *user)
{
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)user;
ILibDuktape_ScriptContainer_Slave *slave = cmd->container.slave;
ILibDuktape_ScriptContainer_Master *master = (ILibDuktape_ScriptContainer_Master*)((void**)ILibMemory_GetExtraMemory(slave->chain, ILibMemory_CHAIN_CONTAINERSIZE))[0];
int id;
duk_push_string(slave->ctx, cmd->json); // [string]
duk_json_decode(slave->ctx, -1); // [json]
free(cmd);
switch ((id = Duktape_GetIntPropertyValue(slave->ctx, -1, "command", -1)))
{
case SCRIPT_ENGINE_COMMAND_INIT:
ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(slave->ctx, (SCRIPT_ENGINE_SECURITY_FLAGS)master->ChildSecurityFlags, 0, slave->chain, NULL, NULL, NULL, NULL, ILibDuktape_ScriptContainer_Slave_HeapDestroyed, slave);
ILibDuktape_SetNativeUncaughtExceptionHandler(slave->ctx, ILibDuktape_ScriptContainer_NonIsolatedWorker_ExceptionSink, master);
break;
case SCRIPT_ENGINE_COMMAND_EXEC:
{
char *payload;
duk_size_t payloadLen;
payload = (char*)Duktape_GetStringPropertyValueEx(slave->ctx, -1, "base64", NULL, &payloadLen);
payloadLen = ILibBase64Decode((unsigned char*)payload, (int)payloadLen, (unsigned char**)&payload);
if (ILibDuktape_ScriptContainer_CompileJavaScript(slave->ctx, payload, (int)payloadLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx) == 0)
{
// SUCCESS
duk_pop(slave->ctx);
}
else
{
// ERROR
ILibDuktape_Process_UncaughtExceptionEx(slave->ctx, "ScriptContainer Error: ");
duk_pop(slave->ctx);
}
}
break;
case SCRIPT_ENGINE_COMMAND_SEND_JSON:
{
if (slave->emitter != NULL)
{
duk_get_prop_string(slave->ctx, -1, "json"); // [cmd][string]
duk_json_decode(slave->ctx, -1); // [cmd][obj]
duk_push_heapptr(slave->ctx, slave->emitter->object); // [cmd][obj][container]
duk_get_prop_string(slave->ctx, -1, "emit"); // [cmd][obj][container][emit]
duk_swap_top(slave->ctx, -2); // [cmd][obj][emit][this]
duk_push_string(slave->ctx, "data"); // [cmd][obj][emit][this][data]
duk_dup(slave->ctx, -4); // [cmd][obj][emit][this][data][obj]
if (duk_pcall_method(slave->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(slave->ctx); }
duk_pop_2(slave->ctx); // [cmd]
}
}
break;
case SCRIPT_ENGINE_COMMAND_EXIT:
slave->noRespond = Duktape_GetIntPropertyValue(slave->ctx, -1, "noResponse", 0);
duk_pop(slave->ctx);
duk_destroy_heap(slave->ctx);
return;
}
duk_pop(slave->ctx); // ...
}
void ILibDuktape_ScriptContainer_NonIsolatedWorker(void *arg)
{
ILibDuktape_ScriptContainer_Master *master = (ILibDuktape_ScriptContainer_Master*)arg;
ILibDuktape_ScriptContainer_Slave *slave = ILibMemory_AllocateA(sizeof(ILibDuktape_ScriptContainer_Slave));
char json[] = "{\"command\": \"0\"}";
slave->chain = ILibCreateChainEx(2 * sizeof(void*));
((void**)ILibMemory_GetExtraMemory(slave->chain, ILibMemory_CHAIN_CONTAINERSIZE))[0] = master;
((void**)ILibMemory_GetExtraMemory(slave->chain, ILibMemory_CHAIN_CONTAINERSIZE))[1] = slave;
master->PeerChain = slave->chain;
slave->ctx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal();
duk_push_heap_stash(slave->ctx);
duk_push_pointer(slave->ctx, slave);
duk_put_prop_string(slave->ctx, -2, ILibDuktape_ScriptContainer_SlavePtr);
duk_pop(slave->ctx);
ILibDuktape_ScriptContainer_NonIsolated_Command* cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
cmd->container.master = master;
memcpy_s(cmd->json, sizeof(json), json, sizeof(json));
ILibChain_RunOnMicrostackThread(master->chain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster, cmd);
ILibStartChain(slave->chain);
if (slave->noRespond == 0)
{
cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(64 + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
cmd->container.master = master;
sprintf_s(cmd->json, 64, "{\"command\": \"128\", \"exitCode\": \"%d\"}", slave->exitCode);
ILibChain_RunOnMicrostackThread(master->chain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster, cmd);
}
}
duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
{
char *exePath;
@@ -1575,6 +2063,12 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
char *buffer;
char header[4];
ILibProcessPipe_SpawnTypes spawnType = (duk_get_top(ctx) > 2 && duk_is_number(ctx, 2)) ? (ILibProcessPipe_SpawnTypes)duk_require_int(ctx, 2) : ILibProcessPipe_SpawnTypes_DEFAULT;
int processIsolation = 1;
if (duk_get_top(ctx) > 0 && duk_is_object(ctx, 0))
{
processIsolation = Duktape_GetIntPropertyValue(ctx, 0, "processIsolation", 1);
}
duk_push_heap_stash(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_ExePath);
@@ -1584,6 +2078,7 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
manager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
duk_push_object(ctx); // [container]
ILibDuktape_WriteID(ctx, "ScriptContainer.master");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_ScriptContainer_Master)); // [container][buffer]
master = (ILibDuktape_ScriptContainer_Master*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_MasterPtr); // [container]
@@ -1592,9 +2087,9 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
master->ctx = ctx;
master->emitter = ILibDuktape_EventEmitter_Create(ctx);
master->chain = Duktape_GetChain(ctx);
ILibDuktape_EventEmitter_CreateEvent(master->emitter, "exit", &(master->OnExit));
ILibDuktape_EventEmitter_CreateEvent(master->emitter, "error", &(master->OnError));
ILibDuktape_EventEmitter_CreateEvent(master->emitter, "data", &(master->OnJSON));
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "exit");
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "data");
ILibDuktape_CreateProperty_InstanceMethod(ctx, "exit", ILibDuktape_ScriptContainer_Exit, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(master->ctx, "ExecuteScript", ILibDuktape_ScriptContainer_ExecuteScript, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(master->ctx, "ExecuteString", ILibDuktape_ScriptContainer_ExecuteString, DUK_VARARGS);
@@ -1602,28 +2097,43 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
ILibDuktape_CreateInstanceMethod(master->ctx, "addModule", ILibDuktape_ScriptContainer_Master_AddModule, 2);
ILibDuktape_CreateFinalizer(master->ctx, ILibDuktape_ScriptContainer_Finalizer);
unsigned int executionTimeout = (unsigned int)duk_require_int(ctx, 0);
unsigned int securityFlags = (unsigned int)duk_require_int(ctx, 1) | SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS;
if (processIsolation)
{
// We're going to spawn a child process to run this ScriptContainer
unsigned int executionTimeout = (unsigned int)duk_require_int(ctx, 0);
master->ChildSecurityFlags = (unsigned int)duk_require_int(ctx, 1) | SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS;
master->child = ILibProcessPipe_Manager_SpawnProcessEx2(manager, exePath, (char * const*)param, spawnType, 2 * sizeof(void*));
if (master->child == NULL) { return(ILibDuktape_Error(ctx, "ScriptContainer.Create(): Error spawning child process, using [%s]", exePath)); }
master->child = ILibProcessPipe_Manager_SpawnProcessEx2(manager, exePath, (char * const*)param, spawnType, 2 * sizeof(void*));
if (master->child == NULL) { return(ILibDuktape_Error(ctx, "ScriptContainer.Create(): Error spawning child process, using [%s]", exePath)); }
duk_push_true(ctx);
duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_ProcessIsolated);
duk_push_object(ctx); // [container][obj]
duk_push_int(ctx, (int)SCRIPT_ENGINE_COMMAND_INIT);
duk_put_prop_string(ctx, -2, "command");
duk_push_int(ctx, (int)executionTimeout);
duk_put_prop_string(ctx, -2, "executionTimeout");
duk_push_int(ctx, (int)master->ChildSecurityFlags);
duk_put_prop_string(ctx, -2, "securityFlags");
duk_json_encode(ctx, -1);
buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
duk_push_object(ctx); // [container][obj]
duk_push_int(ctx, (int)SCRIPT_ENGINE_COMMAND_INIT);
duk_put_prop_string(ctx, -2, "command");
duk_push_int(ctx, (int)executionTimeout);
duk_put_prop_string(ctx, -2, "executionTimeout");
duk_push_int(ctx, (int)securityFlags);
duk_put_prop_string(ctx, -2, "securityFlags");
duk_json_encode(ctx, -1);
buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
duk_swap_top(ctx, -2); // [json][container]
duk_swap_top(ctx, -2); // [json][container]
((int*)header)[0] = (int)bufferLen + 4;
ILibProcessPipe_Process_AddHandlers(master->child, SCRIPT_ENGINE_PIPE_BUFFER_SIZE, ILibDuktape_ScriptContainer_ExitSink, ILibDuktape_ScriptContainer_StdOutSink, ILibDuktape_ScriptContainer_StdErrSink, ILibDuktape_ScriptContainer_SendOkSink, master);
ILibProcessPipe_Process_WriteStdIn(master->child, header, sizeof(header), ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);
((int*)header)[0] = (int)bufferLen + 4;
ILibProcessPipe_Process_AddHandlers(master->child, SCRIPT_ENGINE_PIPE_BUFFER_SIZE, ILibDuktape_ScriptContainer_ExitSink, ILibDuktape_ScriptContainer_StdOutSink, ILibDuktape_ScriptContainer_StdErrSink, ILibDuktape_ScriptContainer_SendOkSink, master);
ILibProcessPipe_Process_WriteStdIn(master->child, header, sizeof(header), ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);
}
else
{
// We're going to spawn a thread to host this Script Container
duk_push_false(ctx);
duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_ProcessIsolated);
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "ready");
master->PeerThread = ILibSpawnNormalThread(ILibDuktape_ScriptContainer_NonIsolatedWorker, master);
master->ChildSecurityFlags = Duktape_GetIntPropertyValue(ctx, 0, "permissions", 0);
}
return 1;
}
void ILibDuktape_ScriptContainer_PUSH_MASTER(duk_context *ctx, void *chain)
@@ -1653,8 +2163,9 @@ void ILibDuktape_ScriptContainer_PUSH_SLAVE(duk_context *ctx, void *chain)
duk_pop(ctx); // ...
duk_push_object(ctx);
ILibDuktape_WriteID(ctx, "ScriptContainer.slave");
slave->emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEvent(slave->emitter, "data", &(slave->OnData));
ILibDuktape_EventEmitter_CreateEventEx(slave->emitter, "data");
ILibDuktape_CreateInstanceMethod(ctx, "send", ILibDuktape_ScriptContainer_Slave_SendToMaster, 1);
}

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -144,9 +144,10 @@ void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *
void ILibDuktape_ScriptContainer_InitMaster(void *chain, char *exePath, ILibProcessPipe_Manager manager);
int ILibDuktape_ScriptContainer_StartSlave(void *chain, ILibProcessPipe_Manager manager);
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal();
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_context *ctx, SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser);
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx2(SCRIPT_ENGINE_SETTINGS *settings);
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser);
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(securityFlags, executionTimeout, chain, argList, db, exePath, pipeManager, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal(), (securityFlags), (executionTimeout), (chain), (argList), (db), (exePath), (pipeManager), (exitHandler), (exitUser))
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngine(securityFlags, executionTimeout, chain, pp_argList, db, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx((securityFlags), (executionTimeout), (chain), (pp_argList), (db), NULL, NULL, (exitHandler), (exitUser))
SCRIPT_ENGINE_SETTINGS *ILibDuktape_ScriptContainer_GetSettings(duk_context *ctx);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -179,6 +179,17 @@ duk_ret_t ILibDuktape_SimpleDataStore_Keys(duk_context *ctx)
ILibSimpleDataStore_EnumerateKeys(ds, ILibDuktape_SimpleDataStore_Keys_EnumerationSink, &enumerator);
return 1;
}
duk_ret_t ILibDuktape_SimpleDataStore_Delete(duk_context *ctx)
{
duk_push_this(ctx); // [DataStore]
duk_get_prop_string(ctx, -1, ILibDuktape_DataStore_PTR); // [DataStore][ptr]
ILibSimpleDataStore ds = (ILibSimpleDataStore)duk_get_pointer(ctx, -1);
duk_size_t keyLen;
char *key = (char*)duk_get_lstring(ctx, 0, &keyLen);
ILibSimpleDataStore_DeleteEx(ds, key, (int)keyLen);
return(0);
}
duk_ret_t ILibDuktape_SimpleDataStore_Create(duk_context *ctx)
{
ILibSimpleDataStore dataStore;
@@ -214,6 +225,7 @@ duk_ret_t ILibDuktape_SimpleDataStore_Create(duk_context *ctx)
duk_push_pointer(ctx, dataStore); // [DataStore][RetVal][ds]
duk_put_prop_string(ctx, -2, ILibDuktape_DataStore_PTR);// [DataStore][RetVal]
ILibDuktape_CreateInstanceMethod(ctx, "Delete", ILibDuktape_SimpleDataStore_Delete, 1);
ILibDuktape_CreateInstanceMethod(ctx, "Put", ILibDuktape_SimpleDataStore_Put, 2);
ILibDuktape_CreateInstanceMethod(ctx, "Get", ILibDuktape_SimpleDataStore_Get, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "Compact", ILibDuktape_SimpleDataStore_Compact, 0);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -44,11 +44,7 @@ typedef struct ILibWebRTC_Duktape_Handlers
void *ConnectionObject;
ILibDuktape_EventEmitter *emitter;
void *OnConnect;
void *OnDataChannel;
void *OnConnectionSendOK;
void *OnCandidate;
void *OnDisconnect;
}ILibWebRTC_Duktape_Handlers;
typedef struct ILibDuktape_WebRTC_DataChannel
{
@@ -56,7 +52,6 @@ typedef struct ILibDuktape_WebRTC_DataChannel
duk_context *ctx;
ILibDuktape_EventEmitter *emitter;
ILibDuktape_DuplexStream *stream;
void *OnAck;
}ILibDuktape_WebRTC_DataChannel;
extern void* ILibWrapper_WebRTC_Connection_GetStunModule(ILibWrapper_WebRTC_Connection connection);
@@ -170,7 +165,8 @@ void ILibDuktape_WebRTC_DataChannel_OnClose(struct ILibWrapper_WebRTC_DataChanne
void ILibDuktape_WebRTC_DataChannel_OnData(struct ILibWrapper_WebRTC_DataChannel* dataChannel, char* data, int dataLen, int dataType)
{
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)dataChannel->userData;
if (ptrs != NULL) { ILibDuktape_DuplexStream_WriteData(ptrs->stream, data, dataLen); }
if (ptrs != NULL) { ILibDuktape_DuplexStream_WriteDataEx(ptrs->stream, dataType == 51 ? 1 : 0, data, dataLen); }
}
duk_ret_t ILibDuktape_WebRTC_DataChannel_Finalizer(duk_context *ctx)
{
@@ -178,12 +174,14 @@ duk_ret_t ILibDuktape_WebRTC_DataChannel_Finalizer(duk_context *ctx)
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)Duktape_GetBuffer(ctx, -1, NULL);
if (ptrs->dataChannel != NULL)
{
printf("WebRTC Data Channel Finalizer on Connection: %p\n", ptrs->dataChannel->parent);
ptrs->dataChannel->userData = NULL;
ILibWrapper_WebRTC_DataChannel_Close(ptrs->dataChannel);
}
return 0;
}
void ILibDuktape_WebRTC_DataChannel_PUSH(duk_context *ctx, ILibWrapper_WebRTC_DataChannel *dataChannel)
{
if (dataChannel == NULL) { duk_push_null(ctx); return; }
@@ -195,6 +193,7 @@ void ILibDuktape_WebRTC_DataChannel_PUSH(duk_context *ctx, ILibWrapper_WebRTC_Da
dataChannel->OnRawData = ILibDuktape_WebRTC_DataChannel_OnData;
duk_push_object(ctx); // [dataChannel]
ILibDuktape_WriteID(ctx, "webRTC.dataChannel");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_WebRTC_DataChannel)); // [dataChannel][buffer]
ptrs = (ILibDuktape_WebRTC_DataChannel*)Duktape_GetBuffer(ctx, -1, NULL);
dataChannel->userData = ptrs;
@@ -209,7 +208,8 @@ void ILibDuktape_WebRTC_DataChannel_PUSH(duk_context *ctx, ILibWrapper_WebRTC_Da
duk_push_int(ctx, dataChannel->streamId);
duk_put_prop_string(ctx, -2, "id");
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "ack", &(ptrs->OnAck));
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "ack");
ptrs->stream = ILibDuktape_DuplexStream_Init(ctx, ILibDuktape_WebRTC_DataChannel_Stream_WriteSink, ILibDuktape_WebRTC_DataChannel_Stream_EndSink,
ILibDuktape_WebRTC_DataChannel_Stream_PauseSink, ILibDuktape_WebRTC_DataChannel_Stream_ResumeSink, ptrs);
}
@@ -221,6 +221,8 @@ duk_ret_t ILibDuktape_WebRTC_ConnectionFactory_Finalizer(duk_context *ctx)
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionFactoryPtr);
factory = (ILibWrapper_WebRTC_ConnectionFactory)duk_get_pointer(ctx, -1);
printf("WebRTC Factory Finalizer: %p\n", factory);
if (factory != NULL && ILibIsChainBeingDestroyed(chain) == 0)
{
ILibWrapper_WebRTC_ConnectionFactory_RemoveFromChain(factory);
@@ -228,48 +230,140 @@ duk_ret_t ILibDuktape_WebRTC_ConnectionFactory_Finalizer(duk_context *ctx)
return 0;
}
#ifdef _WEBRTCDEBUG
void ILibDuktape_WebRTC_Connection_Debug(void* dtlsSession, char* debugField, int data)
{
ILibHashtable *t = ILibChain_GetBaseHashtable(((ILibTransport*)dtlsSession)->ChainLink.ParentChain);
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibHashtable_Get(t, dtlsSession, NULL, 0);
if (ptrs != NULL)
{
if (strcmp(debugField, "OnHold") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_hold"); // [emit][this][name]
}
else if (strcmp(debugField, "OnCongestionWindowSizeChanged") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_congestionWindowSizeChange"); // [emit][this][name]
}
else if (strcmp(debugField, "OnRTTCalculated") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_rttCalculated"); // [emit][this][name]
}
else if (strcmp(debugField, "OnFastRecovery") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_fastRecovery"); // [emit][this][name]
}
else if (strcmp(debugField, "OnLastSackTime") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_lastSackTime"); // [emit][this][name]
}
else if (strcmp(debugField, "OnLastSentTime") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_lastSentTime"); // [emit][this][name]
}
else if (strcmp(debugField, "OnReceiverCredits") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_receiverCredits"); // [emit][this][name]
}
else if (strcmp(debugField, "OnT3RTX") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_t3tx"); // [emit][this][name]
}
else if (strcmp(debugField, "OnSendRetry") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_retransmit"); // [emit][this][name]
}
else if (strcmp(debugField, "OnSACKReceived") == 0)
{
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_sackReceived"); // [emit][this][name]
}
else if (strcmp(debugField, "OnRetryPacket") == 0)
{
duk_push_external_buffer(ptrs->ctx); // [extBuffer]
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_retransmitPacket"); // [extBuffer][emit][this][name]
duk_config_buffer(ptrs->ctx, -4, debugField + 14, data);
duk_push_buffer_object(ptrs->ctx, -4, 0, data, DUK_BUFOBJ_NODEJS_BUFFER);
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop_2(ptrs->ctx); // ...
return;
}
else
{
return;
}
duk_push_int(ptrs->ctx, data); // [emit][this][name][val]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
}
}
#endif
void ILibDuktape_WebRTC_OnConnection(ILibWrapper_WebRTC_Connection connection, int connected)
{
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
if (ptrs->OnConnect != NULL && connected != 0)
if (connected == 0)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnConnect); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onConnect(): "); }
duk_pop(ptrs->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "disconnected"); // [emit][this][disconnected]
duk_del_prop_string(ptrs->ctx, -2, ILibDuktape_WebRTC_ConnectionPtr);
}
else if (ptrs->OnDisconnect != NULL && connected == 0)
else
{
duk_push_heapptr(ptrs->ctx, ptrs->OnDisconnect); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onConnect(): "); }
duk_pop(ptrs->ctx); // ...
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "connected"); // [emit][this][connected]
}
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
#ifdef _WEBRTCDEBUG
ILibHashtable *t = ILibChain_GetBaseHashtable(Duktape_GetChain(ptrs->ctx));
if (connected != 0)
{
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnHold", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnCongestionWindowSizeChanged", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRTTCalculated", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnFastRecovery", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnReceiverCredits", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnT3RTX", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendRetry", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendFastRetry", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRetryPacket", ILibDuktape_WebRTC_Connection_Debug);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSACKReceived", ILibDuktape_WebRTC_Connection_Debug);
ILibHashtable_Put(t, ILibWrapper_WebRTC_Connection2DtlsSession(connection), NULL, 0, ptrs);
}
else
{
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnHold", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnCongestionWindowSizeChanged", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRTTCalculated", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnFastRecovery", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnReceiverCredits", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnT3RTX", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendRetry", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendFastRetry", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRetryPacket", NULL);
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSACKReceived", NULL);
ILibHashtable_Remove(t, ILibWrapper_WebRTC_Connection2DtlsSession(connection), NULL, 0);
}
#endif
}
void ILibDuktape_WebRTC_OnDataChannel(ILibWrapper_WebRTC_Connection connection, ILibWrapper_WebRTC_DataChannel *dataChannel)
{
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
if (ptrs->OnDataChannel != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnDataChannel); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel);// [func][this][dataChannel]
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
duk_pop(ptrs->ctx); // ...
}
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "dataChannel"); // [emit][this][dataChannel]
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel); // [emit][this][dataChannel][dc]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
duk_pop(ptrs->ctx); // ...
}
void ILibDuktape_WebRTC_offer_onCandidate(ILibWrapper_WebRTC_Connection connection, struct sockaddr_in6* candidate)
{
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
if (ptrs->OnCandidate != NULL)
if (candidate != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnCandidate); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [func][this][options]
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "candidate"); // [emit][this][candidate]
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [emit][this][candidate][options]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
duk_pop(ptrs->ctx); // ...
}
}
@@ -307,20 +401,16 @@ duk_ret_t ILibDuktape_WebRTC_setOffer(duk_context *ctx)
}
else
{
duk_push_null(ctx);
return(ILibDuktape_Error(ctx, "WebRTC: Error setting offer. Most likely too many outstanding offers"));
}
return 1;
}
void ILibDuktape_WebRTC_DataChannel_OnAck(struct ILibWrapper_WebRTC_DataChannel* dataChannel)
{
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)dataChannel->userData;
if (ptrs->OnAck != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnAck); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->emitter->object); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.dataChannel.onAck(): "); };
duk_pop(ptrs->ctx); // ...
}
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->emitter->object, "ack"); // [emit][this][ack]
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.dataChannel.onAck(): "); };
duk_pop(ptrs->ctx); // ...
}
duk_ret_t ILibDuktape_WebRTC_createDataChannel(duk_context *ctx)
{
@@ -378,8 +468,13 @@ duk_ret_t ILibDuktape_WebRTC_Connection_Finalizer(duk_context *ctx)
ILibWrapper_WebRTC_Connection connection;
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionPtr);
connection = (ILibWrapper_WebRTC_Connection)duk_get_pointer(ctx, -1);
printf("WebRTCConnection Finalizer on %p\n", (void*)connection);
if (connection == NULL) { return 0; }
#ifdef _WEBRTCDEBUG
ILibHashtable_Remove(ILibChain_GetBaseHashtable(Duktape_GetChain(ctx)), ILibWrapper_WebRTC_Connection2DtlsSession(connection), NULL, 0);
#endif
if (ILibWrapper_WebRTC_Connection_IsConnected(connection) != 0)
{
ILibWrapper_WebRTC_Connection_CloseAllDataChannels(connection);
@@ -398,17 +493,31 @@ duk_ret_t ILibDuktape_WebRTC_CreateConnection(duk_context *ctx)
factory = (ILibWrapper_WebRTC_ConnectionFactory)duk_get_pointer(ctx, -1);
duk_push_object(ctx); // [factory][connection]
ILibDuktape_WriteID(ctx, "webRTC.peerConnection");
connection = ILibWrapper_WebRTC_ConnectionFactory_CreateConnection2(factory, ILibDuktape_WebRTC_OnConnection, ILibDuktape_WebRTC_OnDataChannel, NULL, sizeof(ILibWebRTC_Duktape_Handlers));
ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
ptrs->ctx = ctx;
ptrs->ConnectionObject = duk_get_heapptr(ctx, -1);
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "candidate", &(ptrs->OnCandidate));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "dataChannel", &(ptrs->OnDataChannel));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "connected", &(ptrs->OnConnect));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "disconnected", &(ptrs->OnDisconnect));
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "candidate");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "dataChannel");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "connected");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "disconnected");
#ifdef _WEBRTCDEBUG
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_hold");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_lastSackTime");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_lastSentTime");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_congestionWindowSizeChange");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_fastRecovery");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_rttCalculated");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_receiverCredits");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_t3tx");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_retransmit");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_retransmitPacket");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_sackReceived");
#endif
duk_push_pointer(ctx, connection); // [factory][connection][ptr]
duk_put_prop_string(ctx, -2, ILibDuktape_WebRTC_ConnectionPtr); // [factory][connection]
@@ -429,6 +538,7 @@ void ILibDuktape_WebRTC_Push(duk_context *ctx, void *chain)
ILibWrapper_WebRTC_ConnectionFactory factory;
duk_push_object(ctx); // [factory]
ILibDuktape_WriteID(ctx, "webRTC");
factory = ILibWrapper_WebRTC_ConnectionFactory_CreateConnectionFactory(chain, 0);
duk_push_pointer(ctx, factory); // [factory][ptr]
duk_put_prop_string(ctx, -2, ILibDuktape_WebRTC_ConnectionFactoryPtr); // [factory]

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef ___ILibDuktape_WebRTC___
#define ___ILibDuktape_WebRTC___

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ limitations under the License.
#include "ILibDuktape_Helpers.h"
#include "ILibDuktape_WritableStream.h"
#include "ILibDuktape_EventEmitter.h"
#include "ILibDuktape_Polyfills.h"
#ifdef __DOXY__
/*!
@@ -118,11 +119,13 @@ void ILibDuktape_WritableStream_Ready(ILibDuktape_WritableStream *stream)
}
duk_pop(stream->ctx); // ...
}
else if (stream->OnDrain != NULL)
else
{
duk_push_heapptr(stream->ctx, stream->OnDrain); // [func]
duk_push_heapptr(stream->ctx, stream->obj); // [func][this]
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
duk_push_heapptr(stream->ctx, stream->obj); // [this]
duk_get_prop_string(stream->ctx, -1, "emit"); // [this][emit]
duk_swap_top(stream->ctx, -2); // [emit][this]
duk_push_string(stream->ctx, "drain"); // [emit][this][drain]
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
}
@@ -132,20 +135,17 @@ void ILibDuktape_WritableStream_Ready(ILibDuktape_WritableStream *stream)
else
{
// End of Stream
if (stream->OnFinish != NULL)
{
duk_push_heapptr(stream->ctx, stream->OnFinish); // [func]
duk_push_heapptr(stream->ctx, stream->obj); // [func][this]
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
}
duk_pop(stream->ctx); // ...
}
if (stream->EndSink != NULL)
{
stream->EndSink(stream, stream->WriteSink_User);
}
duk_push_heapptr(stream->ctx, stream->obj); // [stream]
duk_get_prop_string(stream->ctx, -1, "emit"); // [stream][emit]
duk_swap_top(stream->ctx, -2); // [emit][this]
duk_push_string(stream->ctx, "finish"); // [emit][this][finish]
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
duk_pop(stream->ctx); // ...
}
}
@@ -167,6 +167,7 @@ duk_ret_t ILibDuktape_WritableStream_Write(duk_context *ctx)
if (stream->WriteSink != NULL)
{
stream->endBytes = -1;
switch (stream->WriteSink(stream, buffer, (int)bufferLen, stream->WriteSink_User))
{
case ILibTransport_DoneState_COMPLETE:
@@ -192,19 +193,18 @@ duk_ret_t ILibDuktape_WritableStream_Write(duk_context *ctx)
duk_push_false(ctx);
break;
default:
if (stream->OnError != NULL)
duk_push_heapptr(ctx, stream->obj); // [this]
duk_get_prop_string(ctx, -1, "emit"); // [this][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "error"); // [emit][this][error]
duk_push_object(ctx); // [emit][this][error][errorObj]
duk_push_string(ctx, "ILibDuktape_WritableStream_Write");
duk_put_prop_string(ctx, -2, "stack");
duk_push_string(ctx, "ILibDuktape_WriteableStream_Write/Handler returned Error");
duk_put_prop_string(ctx, -2, "message");
if (duk_pcall_method(ctx, 2) != 0) // [retVal]
{
duk_push_heapptr(ctx, stream->OnError); // [func]
duk_push_heapptr(ctx, stream->obj); // [func][this]
duk_push_object(ctx); // [func][this][error]
duk_push_string(ctx, "ILibDuktape_WritableStream_Write");
duk_put_prop_string(ctx, -2, "stack");
duk_push_string(ctx, "ILibDuktape_WriteableStream_Write/Handler returned Error");
duk_put_prop_string(ctx, -2, "message");
if (duk_pcall_method(ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
ILibDuktape_Process_UncaughtException(ctx);
}
duk_push_false(ctx);
break;
@@ -230,10 +230,7 @@ duk_ret_t ILibDuktape_WritableStream_End(duk_context *ctx)
{
if (nargs > 2 && !duk_is_null_or_undefined(ctx, 2))
{
stream->OnFinish = duk_require_heapptr(ctx, 2);
duk_push_this(ctx); // [stream]
duk_dup(ctx, 2); // [stream][flush]
duk_put_prop_string(ctx, -2, "_Finish"); // [stream]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx), "finish", duk_require_heapptr(ctx, 2));
}
stream->endBytes = (int)bufferLen;
if (stream->WriteSink(stream, buffer, (int)bufferLen, stream->WriteSink_User) == ILibTransport_DoneState_INCOMPLETE)
@@ -247,16 +244,14 @@ duk_ret_t ILibDuktape_WritableStream_End(duk_context *ctx)
if (stream->WaitForEnd == 0)
{
// Continue with closing stream
if (stream->OnFinish != NULL)
{
duk_push_heapptr(ctx, stream->OnFinish); // [func]
duk_push_heapptr(ctx, stream->obj); // [func][this]
if (duk_pcall_method(ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
}
if (stream->EndSink != NULL) { stream->EndSink(stream, stream->WriteSink_User); }
duk_push_heapptr(stream->ctx, stream->obj); // [stream]
duk_get_prop_string(stream->ctx, -1, "emit"); // [stream][emit]
duk_swap_top(stream->ctx, -2); // [emit][this]
duk_push_string(stream->ctx, "finish"); // [emit][this][finish]
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
duk_pop(stream->ctx); // ...
}
return 0;
@@ -268,9 +263,20 @@ duk_ret_t ILibDuktape_WritableStream_End_Getter(duk_context *ctx)
}
duk_ret_t ILibDuktape_WritableStream_UnPipeSink(duk_context *ctx)
{
duk_dup(ctx, 0);
duk_push_this(ctx);
//printf("UNPIPE: [%s] => X => [%s]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"));
ILibDuktape_WritableStream *ws;
duk_dup(ctx, 0); // [readable]
duk_push_this(ctx); // [readable][writable]
if (duk_has_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS))
{
duk_get_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS); // [readable][writable][ptr]
ws = (ILibDuktape_WritableStream*)Duktape_GetBuffer(ctx, -1, NULL);
ws->pipedReadable = NULL;
ws->pipedReadable_native = NULL;
duk_pop(ctx); // [readable][writable]
if (g_displayStreamPipeMessages) { printf("UNPIPE: [%s] => X => [%s:%d]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"), ILibDuktape_GetReferenceCount(ctx, -1) - 1); if (g_displayFinalizerMessages) { duk_eval_string(ctx, "_debugGC();"); duk_pop(ctx); } }
}
duk_pop_2(ctx);
return(0);
}
duk_ret_t ILibDuktape_WritableStream_PipeSink(duk_context *ctx)
@@ -289,8 +295,7 @@ duk_ret_t ILibDuktape_WritableStream_PipeSink(duk_context *ctx)
duk_dup(ctx, 0);
duk_push_this(ctx);
//printf("PIPE: [%s] => [%s]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"));
if (g_displayStreamPipeMessages) { printf("PIPE: [%s] => [%s:%d]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"), ILibDuktape_GetReferenceCount(ctx, -1)); }
return(0);
}
@@ -315,11 +320,11 @@ ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, IL
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "pipe");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "unpipe");
ILibDuktape_EventEmitter_CreateEvent(emitter, "drain", &(retVal->OnDrain));
ILibDuktape_EventEmitter_CreateEvent(emitter, "finish", &(retVal->OnFinish));
ILibDuktape_EventEmitter_CreateEvent(emitter, "error", &(retVal->OnError));
ILibDuktape_EventEmitter_CreateEventEx(emitter, "drain");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "finish");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_CreateInstanceMethod(ctx, "write", ILibDuktape_WritableStream_Write, DUK_VARARGS);
ILibDuktape_CreateProperty_InstanceMethod(ctx, "write", ILibDuktape_WritableStream_Write, DUK_VARARGS);
ILibDuktape_CreateEventWithGetter(ctx, "end", ILibDuktape_WritableStream_End_Getter);
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_WritableStream_PipeSink);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -33,14 +33,10 @@ typedef struct ILibDuktape_WritableStream
int JSCreated;
duk_context *ctx;
void *obj;
void *OnDrain;
void *OnWriteFlush;
ILibDuktape_WriteableStream_WriteFlushNative OnWriteFlushEx;
void *OnWriteFlushEx_User;
void *OnError;
void *OnFinish;
char WaitForEnd;
ILibDuktape_WritableStream_WriteHandler WriteSink;

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -69,7 +69,6 @@ typedef struct ILibDuktape_fs_writeStreamData
ILibDuktape_EventEmitter *emitter;
void *fsObject;
void *WriteStreamObject;
void *onClose;
FILE *fPtr;
int fd;
int autoClose;
@@ -82,7 +81,6 @@ typedef struct ILibDuktape_fs_readStreamData
void *ReadStreamObject;
void *fsObject;
ILibDuktape_EventEmitter *emitter;
void *onClose;
FILE *fPtr;
int fd;
int autoClose;
@@ -99,7 +97,6 @@ typedef struct ILibDuktape_fs_watcherData
duk_context *ctx;
void *object;
void *parent;
void *OnChange;
ILibDuktape_EventEmitter *emitter;
#if defined(WIN32)
int recursive;
@@ -240,9 +237,7 @@ duk_ret_t ILibDuktape_fs_openSync(duk_context *ctx)
}
else
{
duk_push_string(ctx, "fs.openSync ERROR");
duk_throw(ctx);
return(DUK_RET_ERROR);
return(ILibDuktape_Error(ctx, "fs.openSync(): Error opening '%s'", path));
}
}
duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
@@ -260,7 +255,7 @@ duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
{
if (duk_is_number(ctx, 4))
{
fseek(f, duk_require_int(ctx, 4), SEEK_CUR);
fseek(f, duk_require_int(ctx, 4), SEEK_SET);
}
bytesRead = (int)fread(buffer + offset, 1, length, f);
duk_push_int(ctx, bytesRead);
@@ -285,7 +280,7 @@ duk_ret_t ILibDuktape_fs_writeSync(duk_context *ctx)
f = ILibDuktape_fs_getFilePtr(ctx, duk_require_int(ctx, 0));
if (f != NULL)
{
if (nargs > 4) { fseek(f, duk_require_int(ctx, 4), SEEK_CUR); }
if (nargs > 4) { fseek(f, duk_require_int(ctx, 4), SEEK_SET); printf("Write: Seeking to %d\n", duk_require_int(ctx, 4)); }
bytesWritten = (int)fwrite(buffer, 1, length, f);
duk_push_int(ctx, bytesWritten);
return 1;
@@ -339,17 +334,14 @@ void ILibDuktape_fs_writeStream_endHandler(struct ILibDuktape_WritableStream *st
data->fPtr = NULL;
}
if (data->ctx != NULL && data->onClose != NULL)
{
// Call the 'close' event on the WriteStream
duk_push_heapptr(data->ctx, data->onClose); // [func]
duk_push_heapptr(data->ctx, data->WriteStreamObject); // [func][this]
if (duk_pcall_method(data->ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx);
}
// Call the 'close' event on the WriteStream
duk_push_heapptr(data->ctx, data->WriteStreamObject); // [this]
duk_get_prop_string(data->ctx, -1, "emit"); // [this][emit]
duk_swap_top(data->ctx, -2); // [emit][this]
duk_push_string(data->ctx, "close"); // [emit][this][close]
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // ...
}
duk_ret_t ILibDuktape_fs_writeStream_finalizer(duk_context *ctx)
{
@@ -413,6 +405,7 @@ duk_ret_t ILibDuktape_fs_createWriteStream(duk_context *ctx)
if (f != NULL)
{
duk_push_object(ctx); // [writeStream]
ILibDuktape_WriteID(ctx, "fs.writeStream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_writeStreamData)); // [writeStream][buffer]
data = (ILibDuktape_fs_writeStreamData*)Duktape_GetBuffer(ctx, -1, NULL);
memset(data, 0, sizeof(ILibDuktape_fs_writeStreamData));
@@ -428,7 +421,7 @@ duk_ret_t ILibDuktape_fs_createWriteStream(duk_context *ctx)
data->emitter = ILibDuktape_EventEmitter_Create(ctx);
data->stream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_fs_writeStream_writeHandler, ILibDuktape_fs_writeStream_endHandler, data);
ILibDuktape_EventEmitter_CreateEvent(data->emitter, "close", &(data->onClose));
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "close");
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_writeStream_finalizer);
return 1;
}
@@ -454,14 +447,15 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender,
sender->paused = 0;
if (data->bytesRead == -1) { data->bytesRead = 1; }
while (sender->paused == 0 && data->bytesRead > 0 && data->bytesLeft < 0)
while (sender->paused == 0 && data->bytesRead > 0 && (data->bytesLeft < 0 || data->bytesLeft > 0))
{
bytesToRead = data->bytesLeft < 0 ? sizeof(data->buffer) : data->bytesLeft;
bytesToRead = data->bytesLeft < 0 ? sizeof(data->buffer) : (data->bytesLeft > sizeof(data->buffer) ? sizeof(data->buffer) : data->bytesLeft);
data->bytesRead = (int)fread(data->buffer, 1, bytesToRead, data->fPtr);
if (data->bytesRead > 0)
{
if (data->bytesLeft > 0) { data->bytesLeft -= data->bytesRead; }
ILibDuktape_readableStream_WriteData(sender, data->buffer, data->bytesRead);
if (data->bytesLeft == 0) { data->bytesRead = 0; }
}
}
if (sender->paused == 0 && data->bytesRead == 0)
@@ -477,14 +471,13 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender,
data->fd = 0;
data->fPtr = NULL;
if (data->onClose != NULL && data->ctx != NULL)
if (data->ctx != NULL && data->ReadStreamObject != NULL)
{
duk_push_heapptr(data->ctx, data->onClose); // [func]
duk_push_heapptr(data->ctx, data->ReadStreamObject); // [func][this]
if (duk_pcall_method(data->ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_push_heapptr(data->ctx, data->ReadStreamObject); // [this]
duk_get_prop_string(data->ctx, -1, "emit"); // [this][emit]
duk_swap_top(data->ctx, -2); // [emit][this]
duk_push_string(data->ctx, "close"); // [emit][this][close]
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // ...
}
}
@@ -551,6 +544,7 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
}
duk_push_object(ctx); // [readStream]
ILibDuktape_WriteID(ctx, "fs.readStream");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_readStreamData)); // [readStream][buffer]
data = (ILibDuktape_fs_readStreamData*)Duktape_GetBuffer(ctx, -1, NULL);
memset(data, 0, sizeof(ILibDuktape_fs_readStreamData));
@@ -564,17 +558,19 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
data->fPtr = f;
data->autoClose = autoClose;
data->ReadStreamObject = duk_get_heapptr(ctx, -1);
data->bytesLeft = end;
data->bytesLeft = end < 0 ? end : (end - start + 1);
data->bytesRead = -1;
data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data);
data->stream->paused = 1;
ILibDuktape_EventEmitter_CreateEvent(data->emitter, "close", &(data->onClose));
//printf("readStream [start: %d, end: %d\n", start, end);
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "close");
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_readStream_finalizer);
if (start != 0)
{
fseek(f, start, SEEK_CUR);
fseek(f, start, SEEK_SET);
}
return 1;
@@ -904,24 +900,23 @@ void ILibDuktape_fs_watch_iocompletionEx(void *chain, void *user)
n = (n->NextEntryOffset != 0) ? ((FILE_NOTIFY_INFORMATION*)((char*)n + n->NextEntryOffset)) : NULL;
}
if (data->OnChange != NULL)
duk_push_heapptr(data->ctx, data->object); // [detail][fsWatcher]
duk_get_prop_string(data->ctx, -1, "emit"); // [detail][fsWatcher][emit]
duk_swap_top(data->ctx, -2); // [detail][emit][this]
duk_push_string(data->ctx, "change"); // [detail][emit][this][change]
duk_push_string(data->ctx, changed == 0 ? "rename" : "change"); // [detail][emit][this][change][type]
if (changed == 0)
{
duk_push_heapptr(data->ctx, data->OnChange); // [detail][change]
duk_push_heapptr(data->ctx, data->object); // [detail][change][fsWatcher]
duk_push_string(data->ctx, changed == 0 ? "rename" : "change"); // [detail][change][fsWatcher][type]
if (changed == 0)
{
duk_get_prop_string(data->ctx, -4, "oldname"); // [detail][listener][fsWatcher][type][fileName]
}
else
{
duk_get_prop_string(data->ctx, -4, "\xFF_FileName"); // [detail][listener][fsWatcher][type][fileName]
}
duk_dup(data->ctx, -5); // [detail][change][fsWatcher][type][fileName][detail]
if (duk_pcall_method(data->ctx, 3) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop(data->ctx); // [detail]
duk_get_prop_string(data->ctx, -4, "oldname"); // [detail][emit][this][change][type][fileName]
}
duk_pop(data->ctx); // ...
else
{
duk_get_prop_string(data->ctx, -4, "\xFF_FileName"); // [detail][emit][this][change][type][fileName]
}
duk_dup(data->ctx, -5); // [detail][emit][this][change][type][fileName][detail]
if (duk_pcall_method(data->ctx, 4) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
duk_pop_2(data->ctx); // ...
memset(data->results, 0, sizeof(data->results));
if (data->h != NULL)
@@ -1001,7 +996,7 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
wd.p = NULL;
wd.i = evt->wd;
watcher = (ILibDuktape_fs_watcherData*)ILibHashtable_Get(data->watchTable, wd.p, NULL, 0);
if (watcher == NULL || watcher->OnChange == NULL) { continue; }
if (watcher == NULL || ILibDuktape_EventEmitter_HasListeners(watcher->emitter, "change") == 0) { continue; }
duk_push_object(watcher->ctx); // [detail]
@@ -1021,21 +1016,19 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
duk_push_string(watcher->ctx, evt->name);
duk_put_prop_string(watcher->ctx, -2, "\xFF_FileName");
}
duk_push_heapptr(watcher->ctx, watcher->OnChange); // [detail][change]
duk_push_heapptr(watcher->ctx, watcher->object); // [detail][change][fsWatcher]
duk_push_string(watcher->ctx, changed == 0 ? "rename" : "change"); // [detail][change][fsWatcher][type]
ILibDuktape_EventEmitter_SetupEmit(watcher->ctx, watcher->object, "change");// [detail][emit][this][change]
duk_push_string(watcher->ctx, changed == 0 ? "rename" : "change"); // [detail][emit][this][change][type]
if (changed == 0)
{
duk_get_prop_string(watcher->ctx, -4, "oldname"); // [detail][listener][fsWatcher][type][fileName]
duk_get_prop_string(watcher->ctx, -5, "oldname"); // [detail][emit][this][change][type][fileName]
}
else
{
duk_get_prop_string(watcher->ctx, -4, "\xFF_FileName"); // [detail][listener][fsWatcher][type][fileName]
duk_get_prop_string(watcher->ctx, -5, "\xFF_FileName"); // [detail][emit][this][change][type][fileName]
}
duk_dup(watcher->ctx, -5); // [detail][change][fsWatcher][type][fileName][detail]
if (duk_pcall_method(watcher->ctx, 3) != 0) { ILibDuktape_Process_UncaughtException(watcher->ctx); }
duk_pop_2(watcher->ctx); // ...
duk_dup(watcher->ctx, -6); // [detail][emit][this][change][type][fileName][detail]
if (duk_pcall_method(watcher->ctx, 4) != 0) { ILibDuktape_Process_UncaughtException(watcher->ctx); }
duk_pop_2(watcher->ctx); // ...
}
}
}
@@ -1099,6 +1092,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
#endif
duk_push_object(ctx); // [FSWatcher]
ILibDuktape_WriteID(ctx, "fs.fsWatcher");
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_watcherData)); // [FSWatcher][data]
data = (ILibDuktape_fs_watcherData*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, FS_WATCHER_DATA_PTR); // [FSWatcher]
@@ -1117,7 +1111,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
ILibDuktape_CreateInstanceMethod(ctx, "close", ILibDuktape_fs_watcher_close, 0);
ILibDuktape_EventEmitter_CreateEvent(data->emitter, "change", &(data->OnChange));
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "change");
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_watcher_finalizer);
for (i = 1; i < nargs; ++i)
@@ -1233,10 +1227,26 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
return(1);
}
duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
{
duk_push_this(ctx); // [fs]
duk_get_prop_string(ctx, -1, "statSync"); // [fs][statSync]
duk_swap_top(ctx, -2); // [statSync][this]
duk_dup(ctx, 0); // [statSync][this][path]
if (duk_pcall_method(ctx, 1) != 0)
{
duk_push_false(ctx);
}
else
{
duk_push_true(ctx);
}
return(1);
}
void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [fs]
ILibDuktape_WriteID(ctx, "fs");
duk_push_pointer(ctx, chain); // [fs][chain]
duk_put_prop_string(ctx, -2, FS_CHAIN_PTR); // [fs]
@@ -1256,6 +1266,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "statSync", ILibDuktape_fs_statSync, 1);
ILibDuktape_CreateInstanceMethod(ctx, "readDrivesSync", ILibDuktape_fs_readDrivesSync, 0);
ILibDuktape_CreateInstanceMethod(ctx, "readFileSync", ILibDuktape_fs_readFileSync, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "existsSync", ILibDuktape_fs_existsSync, 1);
#ifndef _NOFSWATCHER
ILibDuktape_CreateInstanceMethod(ctx, "watch", ILibDuktape_fs_watch, DUK_VARARGS);
#endif

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef ___DUKTAPE_FS___
#define ___DUKTAPE_FS___

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -41,14 +41,12 @@ limitations under the License.
duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
{
ILibHTTPPacket *packet;
duk_get_prop_string(ctx, 0, "PacketPtr");
packet = (ILibHTTPPacket*)duk_get_pointer(ctx, -1);
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "digestClientRequest");// [digestClientRequest]
if (packet->StatusCode == 200)
int statusCode = Duktape_GetIntPropertyValue(ctx, 0, "statusCode", 0);
if (statusCode == 200)
{
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
@@ -60,8 +58,8 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
{
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "error"); // [emit][this][response]
duk_dup(ctx, 0); // [emit][this][response][imsg]
duk_push_string(ctx, "error"); // [emit][this][error]
duk_dup(ctx, 0); // [emit][this][error][imsg]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest: Error dispatching response event"); }
}
@@ -143,8 +141,8 @@ extern void ILibWebServer_Digest_ParseAuthenticationHeader(void* table, char* va
char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void *digestObj, void *optionsObj)
{
int top = duk_get_top(ctx);
int NC;
char *CNONCE;
int NC = 0;
char *CNONCE = NULL;
char *wwwauth, *username, *password;
char *method, *path;
@@ -188,7 +186,9 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
}
else
{
duk_get_prop_string(ctx, -1, DIGEST2CNONCE); // [digest][buffer]
CNONCE = (char*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx); // [digest]
NC = Duktape_GetIntPropertyValue(ctx, -1, DIGEST2NC, 0) + 1;
duk_push_int(ctx, NC); // [digest][NC]
duk_put_prop_string(ctx, -2, DIGEST2NC); // [digest]
@@ -198,14 +198,10 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
util_md5hex(ILibScratchPad2, tmpLen, result3);
duk_pop(ctx); // ...
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\"", username, realm, nonce, path);
if (opaque != NULL) { tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", opaque=\"%s\"", opaque); }
if (qop != NULL)
{
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", qop=\"%s\", nc=%08x, cnonce=\"%s\"", qop, NC, CNONCE);
}
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", response=\"%s\"", result3);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\",realm=\"%s\",nonce=\"%s\",uri=\"%s\"", username, realm, nonce, path);
if (opaque != NULL) { tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ",opaque=\"%s\"", opaque); }
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ",response=\"%s\"", result3);
if (qop != NULL) { tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ",qop=\"%s\",nc=\"%08x\",cnonce=\"%s\"", qop, NC, CNONCE); }
if (realmLen > 0) { realm[realmLen] = '"'; }
if (nonceLen > 0) { nonce[nonceLen] = '"'; }
@@ -305,8 +301,8 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
duk_dup(ctx, -2); // [clientRequest][buffer][clientRequest]
duk_get_prop_string(ctx, -1, "write"); // [clientRequest][buffer][clientRequest][write]
duk_swap_top(ctx, -2); // [clientRequest][buffer][write][this]
duk_swap(ctx, -3, -2); // [clientRequest][write][buffer][this]
duk_swap_top(ctx, -2); // [clientReqeust][write][this][buffer]
duk_dup(ctx, -3); // [clientRequest][buffer][write][this][buffer]
duk_remove(ctx, -4); // [clientRequest][write][this][buffer]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "httpDigest.clientRequest.onResponse(): Error calling clientRequest.write(): "); }
duk_pop(ctx); // [clientRequest]
}
@@ -410,6 +406,12 @@ ILibTransport_DoneState ILibDuktape_httpDigest_http_request_WriteHandler(struct
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_TmpBuffer); // [digestClientRequest]
memcpy_s(tmpBuffer, bufLen, buffer, (size_t)bufferLen);
}
if (stream->endBytes > 0)
{
duk_push_true(ctx);
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_END_CALLED);
}
}
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
@@ -477,6 +479,7 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
void *clientRequest = NULL;
ILibDuktape_EventEmitter *emitter;
char *auth = NULL;
int needCallEnd = 0;
duk_push_this(ctx); // [digest]
duk_get_prop_string(ctx, -1, HTTP_DIGEST); // [digest][http]
@@ -489,6 +492,7 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
duk_dup(ctx, -2); // [digest][request][this][parseUri][this]
duk_dup(ctx, 0); // [digest][request][this][parseUri][this][uri]
duk_call_method(ctx, 1); // [digest][request][this][options]
needCallEnd = 1;
}
else
{
@@ -522,6 +526,13 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_response, DUK_VARARGS); // [once][this][response][method]
duk_push_object(ctx); // [once][this][response][method][digest-clientRequest]
ILibDuktape_WriteID(ctx, "httpDigest.clientRequest");
if (needCallEnd)
{
duk_push_true(ctx);
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_END_CALLED);
}
duk_push_this(ctx); // [once][this][response][method][digest-clientRequest][digest]
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_DIGEST); // [once][this][response][method][digest-clientRequest]
duk_push_heapptr(ctx, clientRequest); // [once][this][response][method][digest-clientRequest][clientRequest]
@@ -557,6 +568,13 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "timeout", -1, "timeout");
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "drain", -1, "drain");
if (needCallEnd)
{
duk_get_prop_string(ctx, -2, "end"); // [clientRequest][digestClientRequest][end]
duk_dup(ctx, -3); // [clientRequest][digestClientRequest][end][this]
duk_call_method(ctx, 0); duk_pop(ctx); // [clientRequest][digestClientRequest]
}
return(1);
}
duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
@@ -566,6 +584,7 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [obj]
ILibDuktape_WriteID(ctx, "httpDigest");
ILibDuktape_CreateEventWithSetterEx(ctx, "clientRequest", ILibDuktape_httpDigest_clientRequest_setter);
ILibDuktape_CreateEventWithSetterEx(ctx, "http", ILibDuktape_httpDigest_http_setter);
emitter = ILibDuktape_EventEmitter_Create(ctx);
@@ -580,6 +599,7 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
duk_put_prop_string(ctx, -2, DIGEST_PASSWORD);
duk_push_fixed_buffer(ctx, 16);
util_randomtext(16, (char*)Duktape_GetBuffer(ctx, -1, NULL));
((char*)Duktape_GetBuffer(ctx, -1, NULL))[15] = 0;
duk_put_prop_string(ctx, -2, DIGEST2CNONCE);
duk_push_int(ctx, 0);
duk_put_prop_string(ctx, -2, DIGEST2NC);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,10 +34,6 @@ typedef struct ILibDuktape_net_socket
void *net;
void *duplexStream;
void *chain;
void *OnConnect;
void *OnClose;
void *OnError;
void *OnTimeout;
void *OnSetTimeout;
int unshiftBytes;
ILibDuktape_EventEmitter *emitter;
@@ -53,9 +49,7 @@ typedef struct ILibDuktape_net_server
void *self;
ILibAsyncServerSocket_ServerModule server;
ILibDuktape_EventEmitter *emitter;
void *OnClose;
void *OnListening;
void *OnError;
int isTLS;
}ILibDuktape_net_server;
typedef struct ILibDuktape_net_server_session
{
@@ -66,8 +60,6 @@ typedef struct ILibDuktape_net_server_session
ILibDuktape_DuplexStream *stream;
int unshiftBytes;
void *OnTimeout;
}ILibDuktape_net_server_session;
int ILibDuktape_TLS_ctx2socket = -1;
@@ -83,6 +75,7 @@ int ILibDuktape_TLS_ctx2server = -1;
#define ILibDuktape_SERVER2ContextTable "\xFF_Server2ContextTable"
#define ILibDuktape_SERVER2OPTIONS "\xFF_ServerToOptions"
#define ILibDuktape_SERVER2LISTENOPTIONS "\xFF_ServerToListenOptions"
#define ILibDuktape_TLSSocket2SecureContext "\xFF_TLSSocket2SecureContext"
extern void ILibAsyncServerSocket_RemoveFromChain(ILibAsyncServerSocket_ServerModule serverModule);
@@ -143,28 +136,34 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
return;
}
#endif
if (ptrs->OnConnect != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnConnect); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->object); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ptrs->ctx);
}
duk_pop(ptrs->ctx); // ...
}
duk_push_heapptr(ptrs->ctx, ptrs->object); // [this]
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
duk_swap_top(ptrs->ctx, -2); // [emit][this]
duk_push_string(ptrs->ctx, "connect"); // [emit][this][connect]
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
}
else if(ptrs->OnError != NULL)
else
{
duk_push_heapptr(ptrs->ctx, ptrs->OnError); // [func]
ILibDuktape_net_socket_PUSH(ptrs->ctx, socketModule); // [func][this]
duk_push_object(ptrs->ctx); // [func][this][error]
duk_push_string(ptrs->ctx, "Connection Failed"); // [func][this][error][msg]
duk_put_prop_string(ptrs->ctx, -2, "message"); // [func][this][error]
if (duk_pcall_method(ptrs->ctx, 1) != 0) // [retVal]
duk_push_heapptr(ptrs->ctx, ptrs->object); // [this]
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
duk_swap_top(ptrs->ctx, -2); // [emit][this]
duk_push_string(ptrs->ctx, "error"); // [emit][this][error]
duk_push_object(ptrs->ctx); // [emit][this][error][errorObj]
#ifndef MICROSTACK_NOTLS
if (ptrs->ssl != NULL && ILibAsyncSocket_TLS_WasHandshakeError(socketModule))
{
ILibDuktape_Process_UncaughtException(ptrs->ctx);
duk_push_string(ptrs->ctx, "TLS Handshake Error"); // [emit][this][error][errorObj][msg]
}
else
{
duk_push_string(ptrs->ctx, "Connection Failed"); // [emit][this][error][errorObj][msg]
}
#else
duk_push_string(ptrs->ctx, "Connection Failed"); // [emit][this][error][errorObj][msg]
#endif
duk_put_prop_string(ptrs->ctx, -2, "message"); // [emit][this][error][errorObj]
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
}
}
@@ -338,13 +337,13 @@ duk_ret_t ILibDuktape_net_socket_address(duk_context *ctx)
void ILibDuktape_net_socket_timeoutSink(ILibAsyncSocket_SocketModule socketModule, void *user)
{
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
if (ptrs->OnTimeout != NULL)
{
duk_push_heapptr(ptrs->ctx, ptrs->OnTimeout); // [func]
duk_push_heapptr(ptrs->ctx, ptrs->object); // [func][this]
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
}
duk_push_heapptr(ptrs->ctx, ptrs->object); // [this]
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
duk_swap_top(ptrs->ctx, -2); // [emit][this]
duk_push_string(ptrs->ctx, "timeout"); // [emit][this][timeout]
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
duk_pop(ptrs->ctx); // ...
}
duk_ret_t ILibDuktape_net_socket_setTimeout(duk_context *ctx)
{
@@ -378,9 +377,6 @@ duk_ret_t ILibDuktape_net_socket_finalizer(duk_context *ctx)
if (ptrs->socketModule != NULL)
{
if (ILibAsyncSocket_IsConnected(ptrs->socketModule) != 0) { ILibAsyncSocket_Disconnect(ptrs->socketModule); }
#ifndef MICROSTACK_NOTLS
if (ptrs->ssl_ctx != NULL) { SSL_CTX_free(ptrs->ssl_ctx); ptrs->ssl_ctx = NULL; }
#endif
ILibChain_SafeRemove(chain, ptrs->socketModule);
}
@@ -423,10 +419,10 @@ void ILibDuktape_net_socket_PUSH(duk_context *ctx, ILibAsyncSocket_SocketModule
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
ptrs->duplexStream = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_net_socket_WriteHandler, ILibDuktape_net_socket_EndHandler, ILibDuktape_net_socket_PauseHandler, ILibDuktape_net_socket_ResumeHandler, ILibDuktape_net_socket_unshift, ptrs);
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "close", &(ptrs->OnClose));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "connect", &(ptrs->OnConnect));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "error", &(ptrs->OnError));
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "timeout", &(ptrs->OnTimeout));
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "close");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "connect");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "timeout");
ILibDuktape_CreateProperty_InstanceMethod(ctx, "connect", ILibDuktape_net_socket_connect, DUK_VARARGS);
@@ -576,7 +572,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
session->emitter = ILibDuktape_EventEmitter_Create(ptr->ctx);
ILibDuktape_EventEmitter_CreateEvent(session->emitter, "timeout", &(session->OnTimeout));
ILibDuktape_EventEmitter_CreateEventEx(session->emitter, "timeout");
session->stream = ILibDuktape_DuplexStream_InitEx(ptr->ctx, ILibDuktape_net_server_WriteSink, ILibDuktape_net_server_EndSink,
ILibDuktape_net_server_PauseSink, ILibDuktape_net_server_ResumeSink, ILibDuktape_net_server_unshiftSink, session);
@@ -587,7 +583,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
void ILibDuktape_net_server_OnDisconnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
{
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
ILibDuktape_DuplexStream_WriteEnd(session->stream);
ILibDuktape_DuplexStream_Closed(session->stream);
}
void ILibDuktape_net_server_OnReceive(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, char* buffer, int *p_beginPointer, int endPointer, ILibAsyncServerSocket_OnInterrupt *OnInterrupt, void **user, int *PAUSE)
{
@@ -689,34 +685,37 @@ duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
ILibAsyncServerSocket_SetTag(server->server, server);
#ifndef MICROSTACK_NOTLS
{
duk_push_this(ctx); // [server]
if (duk_has_prop_string(ctx, -1, "addContext"))
if (server->isTLS)
{
duk_get_prop_string(ctx, -1, "addContext"); // [server][addContext]
duk_swap_top(ctx, -2); // [addContext][this]
duk_push_string(ctx, "*"); // [addContext][this][*]
duk_eval_string(ctx, "require('tls');"); // [addContext][this][*][tls]
duk_get_prop_string(ctx, -1, "createSecureContext"); // [addContext][this][*][tls][createSecureContext]
duk_swap_top(ctx, -2); // [addContext][this][*][createSecureContext][this]
duk_get_prop_string(ctx, -4, ILibDuktape_SERVER2OPTIONS); // [addContext][this][*][createSecureContext][this][options]
duk_call_method(ctx, 1); // [addContext][this][*][secureContext]
duk_call_method(ctx, 2); duk_pop(ctx); // ...
}
else
{
duk_pop(ctx); // ...
duk_push_this(ctx); // [server]
if (duk_has_prop_string(ctx, -1, "addContext"))
{
duk_get_prop_string(ctx, -1, "addContext"); // [server][addContext]
duk_swap_top(ctx, -2); // [addContext][this]
duk_push_string(ctx, "*"); // [addContext][this][*]
duk_eval_string(ctx, "require('tls');"); // [addContext][this][*][tls]
duk_get_prop_string(ctx, -1, "createSecureContext"); // [addContext][this][*][tls][createSecureContext]
duk_swap_top(ctx, -2); // [addContext][this][*][createSecureContext][this]
duk_get_prop_string(ctx, -4, ILibDuktape_SERVER2OPTIONS); // [addContext][this][*][createSecureContext][this][options]
duk_call_method(ctx, 1); // [addContext][this][*][secureContext]
duk_call_method(ctx, 2); duk_pop(ctx); // ...
}
else
{
duk_pop(ctx); // ...
}
}
}
#endif
if (server->OnListening != NULL)
{
duk_push_heapptr(server->ctx, server->OnListening); // [func]
duk_push_heapptr(server->ctx, server->self); // [func][this]
if (duk_pcall_method(server->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(server->ctx, "net.server.listen(): Error "); }
duk_pop(server->ctx); // ...
}
duk_push_heapptr(server->ctx, server->self); // [this]
duk_get_prop_string(server->ctx, -1, "emit"); // [this][emit]
duk_swap_top(server->ctx, -2); // [emit][this]
duk_push_string(server->ctx, "listening"); // [emit][this][listenting]
if (duk_pcall_method(server->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(server->ctx, "net.server.listen(): Error "); }
duk_pop(server->ctx); // ...
#ifndef WIN32
ignore_result(backlog);
#endif
@@ -783,11 +782,12 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
server = (ILibDuktape_net_server*)Duktape_GetBuffer(ctx, -1, NULL);
memset(server, 0, sizeof(ILibDuktape_net_server));
duk_put_prop_string(ctx, -2, ILibDuktape_net_Server_buffer); // [server]
server->isTLS = isTLS;
server->self = duk_get_heapptr(ctx, -1);
server->ctx = ctx;
server->emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "close", &(server->OnClose));
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "close");
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "connection");
#ifndef MICROSTACK_NOTLS
if (isTLS)
@@ -799,8 +799,8 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
if (ILibDuktape_TLS_ctx2server < 0) { ILibDuktape_TLS_ctx2server = SSL_get_ex_new_index(0, "ILibDuktape_TLS_Server index", NULL, NULL, NULL); }
}
#endif
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "error", &(server->OnError));
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "listening", &(server->OnListening));
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "listening");
ILibDuktape_CreateInstanceMethod(ctx, "listen", ILibDuktape_net_server_listen, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "address", ILibDuktape_net_server_address, 0);
@@ -816,6 +816,13 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
if (duk_is_object(ctx, i))
{
// Options
if (isTLS && !duk_has_prop_string(ctx, i, "secureProtocol"))
{
duk_dup(ctx, i); // [options]
duk_push_string(ctx, "SSLv23_server_method"); // [options][secureProtocol]
duk_put_prop_string(ctx, -2, "secureProtocol"); // [options]
duk_pop(ctx); // ...
}
}
}
@@ -974,7 +981,7 @@ int ILibDuktape_TLS_verify(int preverify_ok, X509_STORE_CTX *storectx)
if (Duktape_GetBooleanProperty(data->ctx, -1, "rejectUnauthorized", 1)) { duk_pop_2(data->ctx); return(preverify_ok); }
void *OnVerify = Duktape_GetHeapptrProperty(data->ctx, -1, "checkServerIdentity");
if (OnVerify == NULL) { return(1); }
if (OnVerify == NULL) { duk_pop_2(data->ctx); return(1); }
duk_push_heapptr(data->ctx, OnVerify); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
@@ -1141,10 +1148,6 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
ILibAsyncSocket_SocketModule module = ILibCreateAsyncSocketModuleWithMemory(Duktape_GetChain(ctx), 4096, ILibDuktape_net_socket_OnData, ILibDuktape_net_socket_OnConnect, ILibDuktape_net_socket_OnDisconnect, ILibDuktape_net_socket_OnSendOK, sizeof(ILibDuktape_net_socket));
ILibDuktape_net_socket *data = (ILibDuktape_net_socket*)((ILibChain_Link*)module)->ExtraMemoryPtr;
data->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_set_options(data->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_PEER, ILibDuktape_TLS_verify); /* Ask for authentication */
if (ILibDuktape_TLS_ctx2socket < 0)
{
ILibDuktape_TLS_ctx2socket = SSL_get_ex_new_index(0, "ILibDuktape_TLS index", NULL, NULL, NULL);
@@ -1152,6 +1155,28 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
ILibDuktape_net_socket_PUSH(ctx, module); // [socket]
ILibDuktape_WriteID(ctx, "tls.socket");
duk_dup(ctx, 0); // [socket][options]
if (duk_has_prop_string(ctx, -1, "secureContext"))
{
duk_get_prop_string(ctx, -1, "secureContext"); // [socket][options][secureContext]
}
else
{
duk_push_this(ctx); // [socket][options][tls]
duk_get_prop_string(ctx, -1, "createSecureContext"); // [socket][options][tls][createSecureContext]
duk_swap_top(ctx, -2); // [socket][options][createSecureContext][this]
duk_dup(ctx, -3); // [socket][options][createSecureContext][this][options]
duk_call_method(ctx, 1); // [socket][options][secureContext]
}
if ((data->ssl_ctx = (SSL_CTX*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_SecureContext2SSLCTXPTR)) == NULL)
{
return(ILibDuktape_Error(ctx, "Invalid SecureContext Object"));
}
SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_PEER, ILibDuktape_TLS_verify); /* Ask for authentication */
duk_remove(ctx, -2); // [socket][secureContext]
duk_put_prop_string(ctx, -2, ILibDuktape_TLSSocket2SecureContext);
duk_dup(ctx, 0); // [socket][options]
duk_put_prop_string(ctx, -2, ILibDuktape_SOCKET2OPTIONS); // [socket]
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "secureConnect");
@@ -1197,6 +1222,7 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
SSL_set_ex_data(data->ssl, ILibDuktape_TLS_ctx2socket, data);
SSL_set_tlsext_host_name(data->ssl, host);
}
return(1);
}
duk_ret_t ILibDuktape_TLS_secureContext_Finalizer(duk_context *ctx)
@@ -1211,6 +1237,7 @@ duk_ret_t ILibDuktape_TLS_secureContext_Finalizer(duk_context *ctx)
duk_ret_t ILibDuktape_TLS_createSecureContext(duk_context *ctx)
{
duk_push_object(ctx); // [secureContext]
ILibDuktape_WriteID(ctx, "tls.secureContext");
duk_push_fixed_buffer(ctx, sizeof(struct util_cert)); // [secureContext][cert]
struct util_cert *cert = (struct util_cert*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SecureContext2CertBuffer); // [secureContext]
@@ -1218,14 +1245,69 @@ duk_ret_t ILibDuktape_TLS_createSecureContext(duk_context *ctx)
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_TLS_secureContext_Finalizer);
duk_size_t secureProtocolLen;
char *secureProtocol = (char*)Duktape_GetStringPropertyValueEx(ctx, 0, "secureProtocol", "SSLv23_server_method", &secureProtocolLen);
char *secureProtocol = (char*)Duktape_GetStringPropertyValueEx(ctx, 0, "secureProtocol", "SSLv23_method", &secureProtocolLen);
SSL_CTX *ssl_ctx = NULL;
if (secureProtocolLen == 20 && strncmp(secureProtocol, "SSLv23_server_method", 20) == 0)
if (secureProtocolLen == 13 && strncmp(secureProtocol, "SSLv23_method", 13) == 0)
{
ssl_ctx = SSL_CTX_new(SSLv23_server_method());
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
}
else if (secureProtocolLen == 20 && strncmp(secureProtocol, "SSLv23_client_method", 20) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
}
else if (secureProtocolLen == 20 && strncmp(secureProtocol, "SSLv23_server_method", 20) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
}
else if (secureProtocolLen == 12 && strncmp(secureProtocol, "TLSv1_method", 12) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
}
else if (secureProtocolLen == 19 && strncmp(secureProtocol, "TLSv1_client_method", 19) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
}
else if (secureProtocolLen == 19 && strncmp(secureProtocol, "TLSv1_server_method", 19) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
}
else if (secureProtocolLen == 14 && strncmp(secureProtocol, "TLSv1_1_method", 14) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
}
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_1_client_method", 21) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
}
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_1_server_method", 21) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
}
else if (secureProtocolLen == 14 && strncmp(secureProtocol, "TLSv1_2_method", 14) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
}
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_2_client_method", 21) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
}
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_2_server_method", 21) == 0)
{
ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
}
else if (secureProtocolLen == 11 && strncmp(secureProtocol, "DTLS_method", 11) == 0)
{
ssl_ctx = SSL_CTX_new(DTLS_method());
@@ -1266,11 +1348,31 @@ duk_ret_t ILibDuktape_TLS_generateCertificate(duk_context *ctx)
duk_push_fixed_buffer(ctx, len);
memcpy_s((void*)Duktape_GetBuffer(ctx, -1, NULL), len, data, len);
duk_push_buffer_object(ctx, -1, 0, len, DUK_BUFOBJ_NODEJS_BUFFER);
ILibDuktape_WriteID(ctx, "tls.pfxCertificate");
util_free(data);
util_freecert(&cert);
return 1;
}
duk_ret_t ILibDuktape_TLS_loadpkcs7b(duk_context *ctx)
{
duk_size_t len;
char *buffer = (char*)Duktape_GetBuffer(ctx, 0, &len);
int val = util_from_pkcs7b_string(buffer, (int)len, NULL, 0);
char *out;
if (val > 0)
{
duk_push_fixed_buffer(ctx, val);
out = Duktape_GetBuffer(ctx, -1, NULL);
duk_push_buffer_object(ctx, -1, 0, val, DUK_BUFOBJ_NODEJS_BUFFER);
util_from_pkcs7b_string(buffer, (int)len, out, val);
return(1);
}
else
{
return(ILibDuktape_Error(ctx, "Error reading pkcs7b data"));
}
}
void ILibDuktape_tls_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [TLS]
@@ -1278,6 +1380,7 @@ void ILibDuktape_tls_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "connect", ILibDuktape_TLS_connect, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "createSecureContext", ILibDuktape_TLS_createSecureContext, 1);
ILibDuktape_CreateInstanceMethod(ctx, "generateCertificate", ILibDuktape_TLS_generateCertificate, 1);
ILibDuktape_CreateInstanceMethod(ctx, "loadpkcs7b", ILibDuktape_TLS_loadpkcs7b, 1);
}
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
@@ -7,6 +23,7 @@
#include "ILibDuktape_EventEmitter.h"
#include "ILibDuktapeModSearch.h"
#include "ILibDuktape_Helpers.h"
#include "ILibDuktape_Polyfills.h"
#define ILibDuktape_EventEmitter_MaxEventNameLen 255
#define ILibDuktape_EventEmitter_Data "\xFF_EventEmitter_Data"
@@ -127,39 +144,19 @@ void ILibDuktape_EventEmitter_FinalizerEx(ILibHashtable sender, void *Key1, char
duk_pop_2(data->ctx); // ...
}
}
duk_ret_t ILibDuktape_EventEmitter_Finalizer(duk_context *ctx)
int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, char *eventName)
{
ILibDuktape_EventEmitter *data;
duk_get_prop_string(ctx, 0, ILibDuktape_EventEmitter_Data);
data = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
// Check to see if this is the process object going away
if (ILibDuktape_GetProcessObject(ctx) == data->object)
int retVal = 0;
if (emitter->eventTable != NULL)
{
// We need to dispatch the 'exit' event
int exitCode = 0;
duk_push_heapptr(data->ctx, data->object); // [process]
if (duk_has_prop_string(data->ctx, -1, "\xFF_ExitCode"))
ILibLinkedList eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)strnlen_s(eventName, 255));
if (eventList != NULL)
{
duk_get_prop_string(data->ctx, -1, "\xFF_ExitCode"); // [process][exitCode]
exitCode = duk_get_int(data->ctx, -1);
duk_pop(data->ctx); // [process]
retVal = ILibLinkedList_GetCount(eventList);
}
duk_get_prop_string(data->ctx, -1, "emit"); // [process][emit]
duk_swap_top(data->ctx, -2); // [emit][this]
duk_push_string(data->ctx, "exit"); // [emit][this][eventName/exit]
duk_push_int(data->ctx, exitCode); // [emit][this][eventName/exit][exitCode]
duk_pcall_method(data->ctx, 2);
duk_pop(data->ctx);
}
// We need to clear the Native Dispatcher, while destroying the Hashtable
ILibHashtable_DestroyEx(data->eventTable, ILibDuktape_EventEmitter_FinalizerEx, data);
memset(data, 0, sizeof(ILibDuktape_EventEmitter));
return 0;
return(retVal);
}
duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
{
@@ -170,25 +167,24 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
void *self;
int nargs = duk_get_top(ctx);
ILibDuktape_EventEmitter *data;
void *node, *nextNode, *func, *dispatcher;
int i, j, count;
void **hptr;
void *node, *nextNode, *func;
int i, j;
void **emitList;
char *objid;
duk_push_this(ctx);
duk_push_this(ctx); // [this]
objid = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown");
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_Data); // [this][tmp][data]
data = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop_2(ctx); // [this]
self = duk_get_heapptr(ctx, -1);
duk_pop(ctx); // ...
if (data->eventTable == NULL) { duk_push_false(ctx); return(1); } // This probably means the finalizer was already run on the eventEmitter
eventList = ILibHashtable_Get(data->eventTable, NULL, name, (int)nameLen);
if (eventList == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found", name); }
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, name, (int)nameLen);
if (dispatcher == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Internal Error with event '%s'", name); }
if (eventList == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found on object '%s'", name, objid); }
// Copy the list, so we can enumerate with local memory, so the list can be manipulated while we are dispatching
#ifdef WIN32
@@ -213,22 +209,6 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
}
emitList[i] = NULL;
// If no more listeners, we can set the hptr to NULL
if (ILibLinkedList_GetCount(eventList) == 0)
{
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
hptr = (void**)duk_get_pointer(ctx, -1);
*hptr = NULL;
duk_pop(ctx); // [dispatcher][hptrList]
}
duk_pop_2(ctx); // ...
}
// Now that we have all the housekeeping stuff out of the way, we can actually dispatch our events
i = 0;
while ((func = emitList[i++]) != NULL)
@@ -241,13 +221,27 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
}
if (duk_pcall_method(ctx, nargs - 1) != 0)
{
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' threw an exception: %s", name, duk_safe_to_string(ctx, -1)));
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' on '%s' threw an exception: %s", name, objid, duk_safe_to_string(ctx, -1)));
}
duk_pop(ctx); // ...
}
duk_push_boolean(ctx, i > 1 ? 1 : 0);
return(1);
}
int ILibDuktape_EventEmitter_PrependOnce(duk_context *ctx, duk_idx_t i, char *eventName, duk_c_function func)
{
int retVal = 1;
duk_dup(ctx, i); // [this]
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [this][prependOnce]
duk_swap_top(ctx, -2); // [prependOnce][this]
duk_push_string(ctx, eventName); // [prependOnce][this][eventName]
duk_push_c_function(ctx, func, DUK_VARARGS); // [prependOnce][this][eventName][func]
if (duk_pcall_method(ctx, 2) != 0) { retVal = 0; }
duk_pop(ctx); // ...
return(retVal);
}
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr)
{
int retVal = 1;
@@ -315,8 +309,9 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
void *callback = duk_require_heapptr(ctx, 1);
ILibDuktape_EventEmitter *data;
int once;
void *eventList, *node, *dispatcher, **hptr;
int i, count, prepend;
void *eventList, *node;
int prepend;
ILibDuktape_EventEmitter_HookHandler hookHandler = NULL;
duk_push_current_function(ctx);
once = Duktape_GetIntPropertyValue(ctx, -1, "once", 0);
@@ -333,8 +328,7 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
{
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
}
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, propName, (int)propNameLen);
if (dispatcher == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.on(): Internal error with Event '%s'", propName)); }
hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
node = prepend ? ILibLinkedList_AddHead(eventList, callback) : ILibLinkedList_AddTail(eventList, callback);
((int*)ILibLinkedList_GetExtendedMemory(node))[0] = once;
@@ -344,17 +338,7 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
duk_push_heapptr(ctx, callback);
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(callback)); // Save the callback to the tmp object, so it won't get GC'ed
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
hptr = (void**)duk_get_pointer(ctx, -1);
*hptr = dispatcher;
duk_pop(ctx); // [dispatcher][hptrList]
}
if (hookHandler != NULL) { hookHandler(data, propName, callback); }
return 0;
}
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_context *ctx)
@@ -406,36 +390,69 @@ duk_ret_t ILibDuktape_EventEmitter_removeAllListeners(duk_context *ctx)
duk_size_t eventNameLen;
char *eventName = Duktape_GetBuffer(ctx, 0, &eventNameLen);
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx);
void *eventList, *dispatcher;
int count, i;
void **hptr;
void *eventList;
if (emitter != NULL)
{
eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)eventNameLen);
if (eventList == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.removeAllListeners(): Event '%s' not found", eventName)); }
dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, (int)eventNameLen);
if (dispatcher == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.removeAllListeners(): Internal error with Event '%s'", eventName)); }
// NULL was passed, we'll need to clear all listeners.
// Start by setting the Native Dispatcher to NULL, so it appears there are no subscribers
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
hptr = (void**)duk_get_pointer(ctx, -1);
*hptr = NULL;
duk_pop(ctx); // [dispatcher][hptrList]
}
ILibLinkedList_Clear(eventList);
emitter->totalListeners[0] = 0;
}
return(0);
}
void ILibDuktape_EventEmitter_EmbeddedFinalizer2(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
if (Key1 == NULL)
{
char *name = (char*)ILibMemory_AllocateA(Key2Len + 1);
name[Key2Len] = 0;
memcpy_s(name, Key2Len + 1, Key2, Key2Len);
printf("%s ", name);
}
}
duk_ret_t ILibDuktape_EventEmitter_EmbeddedFinalizer(duk_context *ctx)
{
ILibDuktape_EventEmitter_SetupEmit(ctx, duk_get_heapptr(ctx, 0), "~"); // [emit][this][~]
duk_dup(ctx, 0); // [emit][this][~][self]
if (g_displayFinalizerMessages)
{
printf("+-+- Finalizer Event for: %s [%p] -+-+\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), duk_get_heapptr(ctx, -1));
if (strcmp(Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), "UNKNOWN") == 0)
{
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter(ctx, -1);
if (emitter != NULL)
{
printf("UNKNOWN: Listeners=%d\n", ILibDuktape_EventEmitter_HasListeners(emitter, "~"));
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [enumerator]
while (duk_next(ctx, -1, 1))
{
printf("Key: %s, Val: %s\n", duk_get_string(ctx, -2), duk_get_string(ctx, -1));// [enumerator][key][val]
duk_pop_2(ctx); // [enumerator]
}
duk_pop(ctx); // ...
printf("Event Names: ");
if (emitter->eventTable != NULL) { ILibHashtable_Enumerate(emitter->eventTable, ILibDuktape_EventEmitter_EmbeddedFinalizer2, NULL); }
printf("\n");
}
}
}
if (duk_pcall_method(ctx, 2) != 0)
{
ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error in Finalizer: [Invalid C function means you forgot to return 0] ");
}
ILibDuktape_EventEmitter *data = ILibDuktape_EventEmitter_GetEmitter(ctx, 0);
if (data == NULL) { return(ILibDuktape_Error(ctx, "Internal Error")); } // This is deadcode, will never occur, but is here because Klockwork thinks this could happen
// We need to clear the Native Dispatcher, while destroying the Hashtable
ILibHashtable_DestroyEx(data->eventTable, ILibDuktape_EventEmitter_FinalizerEx, data);
memset(data, 0, sizeof(ILibDuktape_EventEmitter));
return(0);
}
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
{
ILibDuktape_EventEmitter *retVal;
@@ -456,10 +473,8 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
retVal->tmpObject = duk_get_heapptr(ctx, -2);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [emitterTmp]
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_EventEmitter_Finalizer);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_TempObject); // [...parent...]
retVal->ctx = ctx;
retVal->object = duk_get_heapptr(ctx, -1);
retVal->eventTable = ILibHashtable_Create();
@@ -489,6 +504,10 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
}
duk_pop(ctx);
ILibDuktape_EventEmitter_CreateEventEx(retVal, "~");
duk_push_c_function(ctx, ILibDuktape_EventEmitter_EmbeddedFinalizer, 1);
duk_set_finalizer(ctx, -2);
return retVal;
}
@@ -505,15 +524,10 @@ duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
duk_size_t propNameLen;
ILibDuktape_EventEmitter *data;
ILibLinkedList eventList = NULL;
void **hptr;
void *dispatcher;
int i, count;
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "name"); // [func][name]
duk_get_prop_string(ctx, -1, "eventName"); // [func][name]
propName = (char*)duk_get_lstring(ctx, -1, &propNameLen);
duk_get_prop_string(ctx, -2, ILibDuktape_EventEmitter_DispatcherFunc); // [func][name][dispatcher]
dispatcher = duk_get_heapptr(ctx, -1);
duk_push_this(ctx); // [obj]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
@@ -526,142 +540,20 @@ duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
if (duk_is_null_or_undefined(ctx, 0))
{
// NULL was passed, we'll need to clear all listeners.
// Start by setting the Native Dispatcher to NULL, so it appears there are no subscribers
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
hptr = (void**)duk_get_pointer(ctx, -1);
*hptr = NULL;
duk_pop(ctx); // [dispatcher][hptrList]
}
ILibLinkedList_Clear(eventList);
duk_push_this(ctx); // [obj]
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [obj][removeAll]
duk_swap_top(ctx, -2); // [removeAll][this]
duk_push_string(ctx, propName); // [removeAll][this][name]
duk_call_method(ctx, 1); duk_pop(ctx);
}
else
{
void *callback = duk_require_heapptr(ctx, 0);
ILibDuktape_EventEmitter_HookHandler hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
ILibLinkedList_AddTail(eventList, callback);
duk_push_heapptr(ctx, data->tmpObject);
duk_push_heapptr(ctx, callback);
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(callback)); // Save callback to tmpObject so it won't get GC'ed
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
hptr = (void**)duk_get_pointer(ctx, -1);
*hptr = dispatcher; // Set this, so from Native, it looks like there is a subscriber.
duk_pop(ctx); // [dispatcher][hptrList]
}
if (hookHandler != NULL)
{
hookHandler(data, propName, callback);
}
ILibDuktape_EventEmitter_AddOn(data, propName, duk_get_heapptr(ctx, 0));
}
return 0;
}
duk_ret_t ILibDuktape_EventEmitter_Dispatcher(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
void *self;
int i;
char *name;
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "name"); // [func][name]
name = (char*)duk_get_string(ctx, -1);
duk_get_prop_string(ctx, -2, "this"); // [func][name][this]
self = duk_get_heapptr(ctx, -1);
duk_get_prop_string(ctx, -1, "emit"); // [func][name][this][emitter]
//-------------------------------------------------------------------------------------------------
duk_push_heapptr(ctx, self); // [emitter][this]
duk_push_string(ctx, name); // [emitter][this][name]
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [emitter][this][name][...args...]
}
duk_call_method(ctx, nargs + 1); // Exception will bubble up.
return 0;
}
duk_ret_t ILibDuktape_EventEmitter_NativeDispatch(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
char *name;
ILibDuktape_EventEmitter_Handler handler;
void *args;
int i = 0;
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "name"); // [func][name]
name = (char*)duk_get_string(ctx, -1);
duk_get_prop_string(ctx, -2, "handler"); // [func][name][handler]
handler = (ILibDuktape_EventEmitter_Handler)duk_get_pointer(ctx, -1);
duk_push_array(ctx); // [func][name][handler][args]
args = duk_get_heapptr(ctx, -1);
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][name][handler][args][...arg...]
duk_put_prop_index(ctx, -2, i); // [func][name][handler][args]
}
duk_push_this(ctx);
handler(ctx, duk_get_heapptr(ctx, -1), name, args);
return 0;
}
int ILibDuktape_EventEmitter_AddSink(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_Handler handler)
{
ILibLinkedList eventList;
void *func;
duk_push_heapptr(emitter->ctx, emitter->tmpObject); // [tmp]
duk_push_c_function(emitter->ctx, ILibDuktape_EventEmitter_NativeDispatch, DUK_VARARGS); // [tmp][dispatch]
duk_push_string(emitter->ctx, eventName); // [tmp][dispatch][name]
duk_put_prop_string(emitter->ctx, -2, "name"); // [tmp][dispatch]
duk_push_pointer(emitter->ctx, handler); // [tmp][dispatch][nativePtr]
duk_put_prop_string(emitter->ctx, -2, "handler"); // [tmp][dispatch]
func = duk_get_heapptr(emitter->ctx, -1);
eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen));
if (eventList == NULL) { return 1; }
((int*)ILibLinkedList_GetExtendedMemory(ILibLinkedList_AddTail(eventList, func)))[0] = 2;
emitter->totalListeners[0]++;
duk_put_prop_string(emitter->ctx, -2, Duktape_GetStashKey(func)); // [tmp]
duk_pop(emitter->ctx); // ...
return 0;
}
void ILibDuktape_EventEmitter_RemoveAllEx(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
ILibDuktape_EventEmitter *data = (ILibDuktape_EventEmitter*)user;
if (Key1 == ILibDuktape_EventEmitter_SetterFunc)
{
// If this is not NULL, this is the JavaScript Setter Func
memcpy_s(ILibScratchPad, sizeof(ILibScratchPad), Key2, Key2Len);
ILibScratchPad[Key2Len] = 0;
duk_push_heapptr(data->ctx, Data); // [Setter]
duk_del_prop_string(data->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST);
duk_push_array(data->ctx); // [Setter][list]
duk_put_prop_string(data->ctx, -2, ILibDuktape_EventEmitter_HPTR_LIST); // [Setter]
duk_pop(data->ctx); // ...
}
}
void ILibDuktape_EventEmitter_RemoveAllListeners(ILibDuktape_EventEmitter *emitter, char *eventName)
{
duk_push_heapptr(emitter->ctx, emitter->object); // [this]
@@ -671,125 +563,45 @@ void ILibDuktape_EventEmitter_RemoveAllListeners(ILibDuktape_EventEmitter *emitt
if (duk_pcall_method(emitter->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(emitter->ctx, "EventEmitter.removeAllListeners(): "); }
duk_pop(emitter->ctx); // ...
}
void ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter *emitter)
void ILibDuktape_EventEmitter_GetEventCountSink(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
if (emitter->eventTable != NULL) { ILibHashtable_Enumerate(emitter->eventTable, ILibDuktape_EventEmitter_RemoveAllEx, emitter); }
}
void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr)
{
int i, count;
void *dispatcher = NULL;
int eventNameLen = (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
if ((dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen)) != NULL)
int *count = (int*)user;
if (Key1 == NULL)
{
// This event already exists... Let's hook up the hptr to the existing dispatcher
duk_push_heapptr(emitter->ctx, dispatcher); // [dispatcher]
if (heapptr != NULL)
{
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = (int)duk_get_length(emitter->ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(emitter->ctx, -1, i); // [dispatcher][hptrList][hptr]
if (duk_get_pointer(emitter->ctx, -1) == heapptr)
{
duk_pop(emitter->ctx); // [dispatcher][hptrList]
duk_del_prop_index(emitter->ctx, -1, i);
break;
}
duk_pop(emitter->ctx); // [dispatcher][hptrList]
}
duk_pop(emitter->ctx); // [dispatcher]
}
else
{
duk_del_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher]
duk_push_array(emitter->ctx); // [dispatcher][hptrList]
duk_put_prop_string(emitter->ctx, -2, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher]
}
duk_pop(emitter->ctx); // ...
++(*count);
}
}
int ILibDuktape_EventEmitter_AddEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr)
int ILibDuktape_EventEmitter_GetEventCount(ILibDuktape_EventEmitter *emitter)
{
ILibLinkedList eventList = NULL;
void *dispatcher = NULL;
int eventNameLen = (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
if ((dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen)) != NULL)
{
// This event already exists... Let's hook up the hptr to the existing dispatcher
duk_push_heapptr(emitter->ctx, dispatcher); // [dispatcher]
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
duk_push_pointer(emitter->ctx, heapptr); // [dispatcher][hptrList][hptr]
duk_put_prop_index(emitter->ctx, -2, (duk_uarridx_t)duk_get_length(emitter->ctx, -2)); // [dispatcher][hptrList]
duk_pop_2(emitter->ctx); // ...
int retVal = 0;
if (emitter->eventTable != NULL) { ILibHashtable_Enumerate(emitter->eventTable, ILibDuktape_EventEmitter_GetEventCountSink, &retVal); }
return(retVal);
}
// Now lets check if there was already a subscriber
if ((eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, eventNameLen)) != NULL && ILibLinkedList_GetCount(eventList) > 0)
{
*heapptr = dispatcher;
}
return 0;
}
return 1;
}
void ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter *emitter, char *eventName)
{
void **heapptr;
duk_push_heapptr(emitter->ctx, emitter->tmpObject); // [emitter]
duk_push_object(emitter->ctx); // [emitter][tmp]
duk_push_fixed_buffer(emitter->ctx, sizeof(void*)); // [emitter][tmp][buffer]
heapptr = (void**)Duktape_GetBuffer(emitter->ctx, -1, NULL);
memset((void*)heapptr, 0, sizeof(void*));
duk_put_prop_string(emitter->ctx, -2, "\xFF_buffer"); // [emitter][tmp]
duk_put_prop_string(emitter->ctx, -2, Duktape_GetStashKey(duk_get_heapptr(emitter->ctx, -1))); // [emitter]
duk_pop(emitter->ctx); // ...
ILibDuktape_EventEmitter_CreateEvent(emitter, eventName, heapptr);
}
void ILibDuktape_EventEmitter_CreateEvent(ILibDuktape_EventEmitter *emitter, char *eventName, void **hptr)
{
void *dispatcher = NULL;
int eventNameLen = (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
if ((dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen)) != NULL)
if (ILibHashtable_Get(emitter->eventTable, NULL, eventName, eventNameLen) != NULL)
{
// This event already exists... Let's hook up the hptr to the existing dispatcher
duk_push_heapptr(emitter->ctx, dispatcher); // [dispatcher]
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
duk_push_pointer(emitter->ctx, hptr); // [dispatcher][hptrList][hptr]
duk_put_prop_index(emitter->ctx, -2, (duk_uarridx_t)duk_get_length(emitter->ctx, -2)); // [dispatcher][hptrList]
duk_pop_2(emitter->ctx); // ...
// This event already exists...
return;
}
duk_push_heapptr(emitter->ctx, emitter->object); // [obj]
// Create the Property Setter
duk_push_string(emitter->ctx, eventName); // [obj][prop]
duk_push_c_function(emitter->ctx, ILibDuktape_EventEmitter_SetEvent, 1); // [obj][prop][setFunc]
duk_push_string(emitter->ctx, eventName); // [obj][prop][setFunc][name]
duk_put_prop_string(emitter->ctx, -2, "name"); // [obj][prop][setFunc]
// Set some custom properties into the setter func, so we can access it later
duk_push_c_function(emitter->ctx, ILibDuktape_EventEmitter_Dispatcher, DUK_VARARGS); // [obj][prop][setFunc][dispatcher]
dispatcher = duk_get_heapptr(emitter->ctx, -1);
duk_push_heapptr(emitter->ctx, emitter->object); // [obj][prop][setFunc][dispatcher][this]
duk_put_prop_string(emitter->ctx, -2, "this"); // [obj][prop][setFunc][dispatcher]
duk_push_string(emitter->ctx, eventName); // [obj][prop][setFunc][dispatcher][name]
duk_put_prop_string(emitter->ctx, -2, "name"); // [obj][prop][setFunc][dispatcher]
duk_push_array(emitter->ctx); // [obj][prop][setFunc][dispatcher][hptrList]
duk_push_pointer(emitter->ctx, hptr); // [obj][prop][setFunc][dispatcher][hptrList][hptr]
duk_put_prop_index(emitter->ctx, -2, 0); // [obj][prop][setFunc][dispatcher][hptrList]
duk_put_prop_string(emitter->ctx, -2, ILibDuktape_EventEmitter_HPTR_LIST); // [obj][prop][setFunc][dispatcher]
duk_put_prop_string(emitter->ctx, -2, ILibDuktape_EventEmitter_DispatcherFunc); // [obj][prop][setFunc]
duk_put_prop_string(emitter->ctx, -2, "eventName"); // [obj][prop][setFunc]
duk_def_prop(emitter->ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_SETTER); // [obj]
duk_pop(emitter->ctx); // ...
ILibHashtable_Put(emitter->eventTable, NULL, eventName, eventNameLen, ILibLinkedList_CreateEx(sizeof(int)));
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen, dispatcher);
}
void *ILibDuktape_EventEmitter_GetDispatcher(ILibDuktape_EventEmitter *emitter, char *eventName)
{
return ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen));
@@ -798,16 +610,13 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits_createEvent(duk_context *ctx)
{
char *name = (char*)duk_require_string(ctx, 0);
ILibDuktape_EventEmitter *emitter;
void **hptr;
duk_push_this(ctx); // [emitterUtils]
duk_get_prop_string(ctx, -1, "emitter"); // [emitterUtils][ptr]
emitter = (ILibDuktape_EventEmitter*)duk_get_pointer(ctx, -1);
duk_pop(ctx); // [emitterUtils]
duk_push_fixed_buffer(ctx, sizeof(void*)); // [emitterUtils][buffer]
hptr = (void**)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, name); // [emitterUtils]
ILibDuktape_EventEmitter_CreateEvent(emitter, name, hptr);
ILibDuktape_EventEmitter_CreateEventEx(emitter, name);
return 0;
}
duk_ret_t ILibDuktape_EventEmitter_Inherits_addMethod(duk_context *ctx)
@@ -878,8 +687,22 @@ duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Sink(duk_context *ctx)
if (duk_pcall_method(ctx, 1 + nargs) != 0) { return(ILibDuktape_Error(ctx, "EventEmitter.ForwardEvent() [%s]: %s", name, duk_safe_to_string(ctx, -1))); }
return(0);
}
duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Finalizer(duk_context *ctx)
{
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "fptr"); // [func][fptr]
duk_get_prop_string(ctx, -1, "targetObject"); // [func][fptr][target]
duk_del_prop_string(ctx, -2, "targetObject");
if (g_displayFinalizerMessages) { printf("EventEmitter.Forwarder[%s]: Deleted reference to [%s] RC=%d\n", Duktape_GetStringPropertyValue(ctx, -3, "targetName", "UNKNOWN"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1) - 1); }
duk_pop_n(ctx, 3);
if (g_displayFinalizerMessages) { duk_eval_string(ctx, "_debugGC();"); duk_pop(ctx); }
return(0);
}
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName)
{
void *fptr;
void *target;
duk_dup(ctx, eventTargetIndex); // [targetObject]
target = duk_get_heapptr(ctx, -1);
@@ -889,12 +712,26 @@ void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSour
duk_swap_top(ctx, -2); // [on][this]
duk_push_string(ctx, sourceEventName); // [on][this][name]
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][name][sink]
fptr = duk_get_heapptr(ctx, -1);
duk_push_heapptr(ctx, target); // [on][this][name][sink][targetObject]
duk_put_prop_string(ctx, -2, "targetObject"); // [on][this][name][sink]
duk_push_string(ctx, targetEventName); // [on][this][name][sink][targetName]
duk_put_prop_string(ctx, -2, "targetName"); // [on][this][name][sink]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
duk_pop(ctx); // ...
duk_dup(ctx, eventSourceIndex); // [sourceObject]
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [sourceObject][prependOnce]
duk_swap_top(ctx, -2); // [prependOnce][this]
duk_push_string(ctx, "~"); // [prependOnce][this]['~']
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
duk_push_heapptr(ctx, fptr); // [prependOnce][this]['~'][func][fptr]
duk_put_prop_string(ctx, -2, "fptr"); // [prependOnce][this]['~'][func]
duk_push_string(ctx, targetEventName); // [prependOnce][this]['~'][func][name]
duk_put_prop_string(ctx, -2, "targetName"); // [prependOnce][this]['~'][func]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
duk_pop(ctx); // ...
}
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func)
{

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,471 @@
/*
* Duktape 1.x compatible module loading framework
*/
#include "duktape.h"
#include "duk_module_duktape.h"
/* (v)snprintf() is missing before MSVC 2015. Note that _(v)snprintf() does
* NOT NUL terminate on truncation, but that's OK here.
* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
*/
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#if 0 /* Enable manually */
#define DUK__ASSERT(x) do { \
if (!(x)) { \
fprintf(stderr, "ASSERTION FAILED at %s:%d: " #x "\n", __FILE__, __LINE__); \
fflush(stderr); \
} \
} while (0)
#define DUK__ASSERT_TOP(ctx,val) do { \
DUK__ASSERT(duk_get_top((ctx)) == (val)); \
} while (0)
#else
#define DUK__ASSERT(x) do { (void) (x); } while (0)
#define DUK__ASSERT_TOP(ctx,val) do { (void) ctx; (void) (val); } while (0)
#endif
static void duk__resolve_module_id(duk_context *ctx, const char *req_id, const char *mod_id) {
duk_uint8_t buf[DUK_COMMONJS_MODULE_ID_LIMIT];
duk_uint8_t *p;
duk_uint8_t *q;
duk_uint8_t *q_last; /* last component */
duk_int_t int_rc;
DUK__ASSERT(req_id != NULL);
/* mod_id may be NULL */
/*
* A few notes on the algorithm:
*
* - Terms are not allowed to begin with a period unless the term
* is either '.' or '..'. This simplifies implementation (and
* is within CommonJS modules specification).
*
* - There are few output bound checks here. This is on purpose:
* the resolution input is length checked and the output is never
* longer than the input. The resolved output is written directly
* over the input because it's never longer than the input at any
* point in the algorithm.
*
* - Non-ASCII characters are processed as individual bytes and
* need no special treatment. However, U+0000 terminates the
* algorithm; this is not an issue because U+0000 is not a
* desirable term character anyway.
*/
/*
* Set up the resolution input which is the requested ID directly
* (if absolute or no current module path) or with current module
* ID prepended (if relative and current module path exists).
*
* Suppose current module is 'foo/bar' and relative path is './quux'.
* The 'bar' component must be replaced so the initial input here is
* 'foo/bar/.././quux'.
*/
if (mod_id != NULL && req_id[0] == '.') {
int_rc = snprintf((char *) buf, sizeof(buf), "%s/../%s", mod_id, req_id);
} else {
int_rc = snprintf((char *) buf, sizeof(buf), "%s", req_id);
}
if (int_rc >= (duk_int_t) sizeof(buf) || int_rc < 0) {
/* Potentially truncated, NUL not guaranteed in any case.
* The (int_rc < 0) case should not occur in practice.
*/
goto resolve_error;
}
DUK__ASSERT(strlen((const char *) buf) < sizeof(buf)); /* at most sizeof(buf) - 1 */
/*
* Resolution loop. At the top of the loop we're expecting a valid
* term: '.', '..', or a non-empty identifier not starting with a period.
*/
p = buf;
q = buf;
for (;;) {
duk_uint_fast8_t c;
/* Here 'p' always points to the start of a term.
*
* We can also unconditionally reset q_last here: if this is
* the last (non-empty) term q_last will have the right value
* on loop exit.
*/
DUK__ASSERT(p >= q); /* output is never longer than input during resolution */
q_last = q;
c = *p++;
if (c == 0) {
goto resolve_error;
} else if (c == '.') {
c = *p++;
if (c == '/') {
/* Term was '.' and is eaten entirely (including dup slashes). */
goto eat_dup_slashes;
}
if (c == '.' && *p == '/') {
/* Term was '..', backtrack resolved name by one component.
* q[-1] = previous slash (or beyond start of buffer)
* q[-2] = last char of previous component (or beyond start of buffer)
*/
p++; /* eat (first) input slash */
DUK__ASSERT(q >= buf);
if (q == buf) {
goto resolve_error;
}
DUK__ASSERT(*(q - 1) == '/');
q--; /* Backtrack to last output slash (dups already eliminated). */
for (;;) {
/* Backtrack to previous slash or start of buffer. */
DUK__ASSERT(q >= buf);
if (q == buf) {
break;
}
if (*(q - 1) == '/') {
break;
}
q--;
}
goto eat_dup_slashes;
}
goto resolve_error;
} else if (c == '/') {
/* e.g. require('/foo'), empty terms not allowed */
goto resolve_error;
} else {
for (;;) {
/* Copy term name until end or '/'. */
*q++ = c;
c = *p++;
if (c == 0) {
/* This was the last term, and q_last was
* updated to match this term at loop top.
*/
goto loop_done;
} else if (c == '/') {
*q++ = '/';
break;
} else {
/* write on next loop */
}
}
}
eat_dup_slashes:
for (;;) {
/* eat dup slashes */
c = *p;
if (c != '/') {
break;
}
p++;
}
}
loop_done:
/* Output #1: resolved absolute name. */
DUK__ASSERT(q >= buf);
duk_push_lstring(ctx, (const char *) buf, (size_t) (q - buf));
/* Output #2: last component name. */
DUK__ASSERT(q >= q_last);
DUK__ASSERT(q_last >= buf);
duk_push_lstring(ctx, (const char *) q_last, (size_t) (q - q_last));
return;
resolve_error:
(void) duk_type_error(ctx, "cannot resolve module id: %s", (const char *) req_id);
}
/* Stack indices for better readability. */
#define DUK__IDX_REQUESTED_ID 0 /* module id requested */
#define DUK__IDX_REQUIRE 1 /* current require() function */
#define DUK__IDX_REQUIRE_ID 2 /* the base ID of the current require() function, resolution base */
#define DUK__IDX_RESOLVED_ID 3 /* resolved, normalized absolute module ID */
#define DUK__IDX_LASTCOMP 4 /* last component name in resolved path */
#define DUK__IDX_DUKTAPE 5 /* Duktape object */
#define DUK__IDX_MODLOADED 6 /* Duktape.modLoaded[] module cache */
#define DUK__IDX_UNDEFINED 7 /* 'undefined', artifact of lookup */
#define DUK__IDX_FRESH_REQUIRE 8 /* new require() function for module, updated resolution base */
#define DUK__IDX_EXPORTS 9 /* default exports table */
#define DUK__IDX_MODULE 10 /* module object containing module.exports, etc */
static duk_ret_t duk__require(duk_context *ctx) {
const char *str_req_id; /* requested identifier */
const char *str_mod_id; /* require.id of current module */
duk_int_t pcall_rc;
/* NOTE: we try to minimize code size by avoiding unnecessary pops,
* so the stack looks a bit cluttered in this function. DUK__ASSERT_TOP()
* assertions are used to ensure stack configuration is correct at each
* step.
*/
/*
* Resolve module identifier into canonical absolute form.
*/
str_req_id = duk_require_string(ctx, DUK__IDX_REQUESTED_ID);
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "id");
str_mod_id = duk_get_string(ctx, DUK__IDX_REQUIRE_ID); /* ignore non-strings */
duk__resolve_module_id(ctx, str_req_id, str_mod_id);
str_req_id = NULL;
str_mod_id = NULL;
/* [ requested_id require require.id resolved_id last_comp ] */
DUK__ASSERT_TOP(ctx, DUK__IDX_LASTCOMP + 1);
/*
* Cached module check.
*
* If module has been loaded or its loading has already begun without
* finishing, return the same cached value (module.exports). The
* value is registered when module load starts so that circular
* references can be supported to some extent.
*/
duk_push_global_stash(ctx);
duk_get_prop_string(ctx, -1, "\xff" "module:Duktape");
duk_remove(ctx, -2); /* Lookup stashed, original 'Duktape' object. */
duk_get_prop_string(ctx, DUK__IDX_DUKTAPE, "modLoaded"); /* Duktape.modLoaded */
duk_require_type_mask(ctx, DUK__IDX_MODLOADED, DUK_TYPE_MASK_OBJECT);
DUK__ASSERT_TOP(ctx, DUK__IDX_MODLOADED + 1);
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
if (duk_get_prop(ctx, DUK__IDX_MODLOADED)) {
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded Duktape.modLoaded[id] ] */
duk_get_prop_string(ctx, -1, "exports"); /* return module.exports */
return 1;
}
DUK__ASSERT_TOP(ctx, DUK__IDX_UNDEFINED + 1);
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined ] */
/*
* Module not loaded (and loading not started previously).
*
* Create a new require() function with 'id' set to resolved ID
* of module being loaded. Also create 'exports' and 'module'
* tables but don't register exports to the loaded table yet.
* We don't want to do that unless the user module search callbacks
* succeeds in finding the module.
*/
/* Fresh require: require.id is left configurable (but not writable)
* so that is not easy to accidentally tweak it, but it can still be
* done with Object.defineProperty().
*
* XXX: require.id could also be just made non-configurable, as there
* is no practical reason to touch it (at least from Ecmascript code).
*/
duk_push_c_function(ctx, duk__require, 1 /*nargs*/);
duk_push_string(ctx, "name");
duk_push_string(ctx, "require");
duk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE); /* not writable, not enumerable, not configurable */
duk_push_string(ctx, "id");
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
duk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_CONFIGURABLE); /* a fresh require() with require.id = resolved target module id */
/* Module table:
* - module.exports: initial exports table (may be replaced by user)
* - module.id is non-writable and non-configurable, as the CommonJS
* spec suggests this if possible
* - module.filename: not set, defaults to resolved ID if not explicitly
* set by modSearch() (note capitalization, not .fileName, matches Node.js)
* - module.name: not set, defaults to last component of resolved ID if
* not explicitly set by modSearch()
*/
duk_push_object(ctx); /* exports */
duk_push_object(ctx); /* module */
duk_push_string(ctx, "exports");
duk_dup(ctx, DUK__IDX_EXPORTS);
duk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE); /* module.exports = exports */
duk_push_string(ctx, "id");
duk_dup(ctx, DUK__IDX_RESOLVED_ID); /* resolved id: require(id) must return this same module */
duk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE); /* module.id = resolved_id; not writable, not enumerable, not configurable */
duk_compact(ctx, DUK__IDX_MODULE); /* module table remains registered to modLoaded, minimize its size */
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 1);
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module ] */
/* Register the module table early to modLoaded[] so that we can
* support circular references even in modSearch(). If an error
* is thrown, we'll delete the reference.
*/
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
duk_dup(ctx, DUK__IDX_MODULE);
duk_put_prop(ctx, DUK__IDX_MODLOADED); /* Duktape.modLoaded[resolved_id] = module */
/*
* Call user provided module search function and build the wrapped
* module source code (if necessary). The module search function
* can be used to implement pure Ecmacsript, pure C, and mixed
* Ecmascript/C modules.
*
* The module search function can operate on the exports table directly
* (e.g. DLL code can register values to it). It can also return a
* string which is interpreted as module source code (if a non-string
* is returned the module is assumed to be a pure C one). If a module
* cannot be found, an error must be thrown by the user callback.
*
* Because Duktape.modLoaded[] already contains the module being
* loaded, circular references for C modules should also work
* (although expected to be quite rare).
*/
duk_push_string(ctx, "(function(require,exports,module){");
/* Duktape.modSearch(resolved_id, fresh_require, exports, module). */
duk_get_prop_string(ctx, DUK__IDX_DUKTAPE, "modSearch"); /* Duktape.modSearch */
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
duk_dup(ctx, DUK__IDX_FRESH_REQUIRE);
duk_dup(ctx, DUK__IDX_EXPORTS);
duk_dup(ctx, DUK__IDX_MODULE); /* [ ... Duktape.modSearch resolved_id last_comp fresh_require exports module ] */
pcall_rc = duk_pcall(ctx, 4 /*nargs*/); /* -> [ ... source ] */
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 3);
if (pcall_rc != DUK_EXEC_SUCCESS) {
/* Delete entry in Duktape.modLoaded[] and rethrow. */
goto delete_rethrow;
}
/* If user callback did not return source code, module loading
* is finished (user callback initialized exports table directly).
*/
if (!duk_is_string(ctx, -1)) {
/* User callback did not return source code, so module loading
* is finished: just update modLoaded with final module.exports
* and we're done.
*/
goto return_exports;
}
/* Finish the wrapped module source. Force module.filename as the
* function .fileName so it gets set for functions defined within a
* module. This also ensures loggers created within the module get
* the module ID (or overridden filename) as their default logger name.
* (Note capitalization: .filename matches Node.js while .fileName is
* used elsewhere in Duktape.)
*/
duk_push_string(ctx, "\n})"); /* Newline allows module last line to contain a // comment. */
duk_concat(ctx, 3);
if (!duk_get_prop_string(ctx, DUK__IDX_MODULE, "filename")) {
/* module.filename for .fileName, default to resolved ID if
* not present.
*/
duk_pop(ctx);
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
}
pcall_rc = duk_pcompile(ctx, DUK_COMPILE_EVAL);
if (pcall_rc != DUK_EXEC_SUCCESS) {
goto delete_rethrow;
}
pcall_rc = duk_pcall(ctx, 0); /* -> eval'd function wrapper (not called yet) */
if (pcall_rc != DUK_EXEC_SUCCESS) {
goto delete_rethrow;
}
/* Module has now evaluated to a wrapped module function. Force its
* .name to match module.name (defaults to last component of resolved
* ID) so that it is shown in stack traces too. Note that we must not
* introduce an actual name binding into the function scope (which is
* usually the case with a named function) because it would affect the
* scope seen by the module and shadow accesses to globals of the same name.
* This is now done by compiling the function as anonymous and then forcing
* its .name without setting a "has name binding" flag.
*/
duk_push_string(ctx, "name");
if (!duk_get_prop_string(ctx, DUK__IDX_MODULE, "name")) {
/* module.name for .name, default to last component if
* not present.
*/
duk_pop(ctx);
duk_dup(ctx, DUK__IDX_LASTCOMP);
}
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);
/*
* Call the wrapped module function.
*
* Use a protected call so that we can update Duktape.modLoaded[resolved_id]
* even if the module throws an error.
*/
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func ] */
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2);
duk_dup(ctx, DUK__IDX_EXPORTS); /* exports (this binding) */
duk_dup(ctx, DUK__IDX_FRESH_REQUIRE); /* fresh require (argument) */
duk_get_prop_string(ctx, DUK__IDX_MODULE, "exports"); /* relookup exports from module.exports in case it was changed by modSearch */
duk_dup(ctx, DUK__IDX_MODULE); /* module (argument) */
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 6);
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func exports fresh_require exports module ] */
pcall_rc = duk_pcall_method(ctx, 3 /*nargs*/);
if (pcall_rc != DUK_EXEC_SUCCESS) {
/* Module loading failed. Node.js will forget the module
* registration so that another require() will try to load
* the module again. Mimic that behavior.
*/
goto delete_rethrow;
}
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module result(ignored) ] */
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2);
/* fall through */
return_exports:
duk_get_prop_string(ctx, DUK__IDX_MODULE, "exports");
duk_compact(ctx, -1); /* compact the exports table */
return 1; /* return module.exports */
delete_rethrow:
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
duk_del_prop(ctx, DUK__IDX_MODLOADED); /* delete Duktape.modLoaded[resolved_id] */
(void) duk_throw(ctx); /* rethrow original error */
return 0; /* not reachable */
}
void duk_module_duktape_init(duk_context *ctx) {
/* Stash 'Duktape' in case it's modified. */
duk_push_global_stash(ctx);
duk_get_global_string(ctx, "Duktape");
duk_put_prop_string(ctx, -2, "\xff" "module:Duktape");
duk_pop(ctx);
/* Register `require` as a global function. */
duk_eval_string(ctx,
"(function(req){"
"var D=Object.defineProperty;"
"D(req,'name',{value:'require'});"
"D(this,'require',{value:req,writable:true,configurable:true});"
"D(Duktape,'modLoaded',{value:Object.create(null),writable:true,configurable:true});"
"})");
duk_push_c_function(ctx, duk__require, 1 /*nargs*/);
duk_call(ctx, 1);
duk_pop(ctx);
}
#undef DUK__ASSERT
#undef DUK__ASSERT_TOP
#undef DUK__IDX_REQUESTED_ID
#undef DUK__IDX_REQUIRE
#undef DUK__IDX_REQUIRE_ID
#undef DUK__IDX_RESOLVED_ID
#undef DUK__IDX_LASTCOMP
#undef DUK__IDX_DUKTAPE
#undef DUK__IDX_MODLOADED
#undef DUK__IDX_UNDEFINED
#undef DUK__IDX_FRESH_REQUIRE
#undef DUK__IDX_EXPORTS
#undef DUK__IDX_MODULE

View File

@@ -0,0 +1,14 @@
#if !defined(DUK_MODULE_DUKTAPE_H_INCLUDED)
#define DUK_MODULE_DUKTAPE_H_INCLUDED
#include "duktape.h"
/* Maximum length of CommonJS module identifier to resolve. Length includes
* both current module ID, requested (possibly relative) module ID, and a
* slash in between.
*/
#define DUK_COMMONJS_MODULE_ID_LIMIT 256
extern void duk_module_duktape_init(duk_context *ctx);
#endif /* DUK_MODULE_DUKTAPE_H_INCLUDED */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -145,46 +145,13 @@ void ILibAsyncServerSocket_OnInterruptSink(ILibAsyncSocket_SocketModule socketMo
void ILibAsyncServerSocket_PreSelect(void* socketModule, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
{
struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
int flags,i;
int i;
UNREFERENCED_PARAMETER( writeset );
UNREFERENCED_PARAMETER( errorset );
UNREFERENCED_PARAMETER( blocktime );
//
// The socket isn't put in listening mode, until the chain is started.
// If this variable == 0, that means we need to do that.
//
if (module->listening == 0)
{
//
// Set the socket to non-block mode, so we can play nice and share the thread
//
#ifdef _WIN32_WCE
flags = 1;
ioctlsocket(module->ListenSocket, FIONBIO, &flags);
#elif WIN32
flags = 1;
ioctlsocket(module->ListenSocket, FIONBIO, (u_long *)(&flags));
#elif _POSIX
flags = fcntl(module->ListenSocket, F_GETFL,0);
fcntl(module->ListenSocket, F_SETFL, O_NONBLOCK | flags);
#endif
//
// Put the socket in Listen, and add it to the fdset for the Select loop
//
module->listening = 1;
listen(module->ListenSocket, 4);
#if defined(WIN32)
#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
#endif
FD_SET(module->ListenSocket, readset);
#if defined(WIN32)
#pragma warning( pop )
#endif
}
else if (module->ListenSocket != ~0)
if (module->ListenSocket != ~0)
{
// Only put the ListenSocket in the readset, if we are able to handle a new socket
for(i = 0; i < module->MaxConnection; ++i)
@@ -714,8 +681,28 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx
//
ILibAsyncSocket_SetReAllocateNotificationCallback(RetVal->AsyncSockets[i], &ILibAsyncServerSocket_OnBufferReAllocated);
}
ILibAddToChain(Chain, RetVal);
//
// Set the socket to non-block mode, so we can play nice and share the thread
//
int flags = 1;
#ifdef _WIN32_WCE
ioctlsocket(RetVal->ListenSocket, FIONBIO, &flags);
#elif WIN32
ioctlsocket(RetVal->ListenSocket, FIONBIO, (u_long *)(&flags));
#elif _POSIX
flags = fcntl(RetVal->ListenSocket, F_GETFL, 0);
fcntl(RetVal->ListenSocket, F_SETFL, O_NONBLOCK | flags);
#endif
RetVal->listening = 1;
listen(RetVal->ListenSocket, 4);
#if defined(WIN32)
#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
#endif
ILibAddToChain(Chain, RetVal);
return RetVal;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -176,6 +176,7 @@ typedef struct ILibAsyncSocketModule
// Added for TLS support
#ifndef MICROSTACK_NOTLS
int TLS_HandshakeError_Occurred;
int SSLConnect;
SSL* ssl;
SSL_CTX *ssl_ctx;
@@ -577,6 +578,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
module->TotalBytesSent += bytesSent;
module->PendingBytesToSend = (unsigned int)(module->writeBioBuffer->length);
}
retVal = ILibAsyncSocket_NOT_ALL_DATA_SENT_YET;
}
else if (bytesSent == module->writeBioBuffer->length)
{
@@ -607,6 +609,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
}
if (lockOverride == 0) { sem_post(&(module->SendLock)); }
if (retVal != ILibAsyncSocket_ALL_DATA_SENT && !ILibIsRunningOnChainThread(module->Transport.ChainLink.ParentChain)) ILibForceUnBlockChain(module->Transport.ChainLink.ParentChain);
return retVal;
}
#endif
@@ -719,7 +722,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
if (lockOverride == 0) { sem_post(&(module->SendLock)); }
if (retVal != ILibAsyncSocket_ALL_DATA_SENT) ILibForceUnBlockChain(module->Transport.ChainLink.ParentChain);
if (retVal != ILibAsyncSocket_ALL_DATA_SENT && !ILibIsRunningOnChainThread(module->Transport.ChainLink.ParentChain)) ILibForceUnBlockChain(module->Transport.ChainLink.ParentChain);
return (retVal);
}
@@ -1034,7 +1037,7 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
int bytesReceived = 0;
int len;
char *temp;
if (Reader->PAUSE > 0)
{
ILibRemoteLogging_printf(ILibChainGetLogger(Reader->Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_Microstack_AsyncSocket, ILibRemoteLogging_Flags_VerbosityLevel_2, "AsyncSocket[%p] is PAUSED", (void*)Reader);
@@ -1105,7 +1108,15 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
default:
// SSL_WANT_READ most likely
sslerror = SSL_get_error(Reader->ssl, sslerror);
ILibAsyncSocket_ProcessEncryptedBuffer(Reader);
if (sslerror == SSL_ERROR_SSL)
{
Reader->TLS_HandshakeError_Occurred = 1;
bytesReceived = -1;
}
else
{
ILibAsyncSocket_ProcessEncryptedBuffer(Reader);
}
break;
}
}
@@ -2288,6 +2299,10 @@ void ILibAsyncSocket_UpdateCallbacks(ILibAsyncSocket_SocketModule module, ILibAs
((ILibAsyncSocketModule*)module)->OnSendOK = OnSendOK;
}
#ifndef MICROSTACK_NOTLS
int ILibAsyncSocket_TLS_WasHandshakeError(ILibAsyncSocket_SocketModule socketModule)
{
return(((struct ILibAsyncSocketModule*)socketModule)->TLS_HandshakeError_Occurred || ((struct ILibAsyncSocketModule*)socketModule)->TLSHandshakeCompleted == 0 ? 1 : 0);
}
//! Gets the Peer's TLS Certificate
/*!
\ingroup TLSGroup

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -239,6 +239,7 @@ void ILibAsyncSocket_SetTimeoutEx(ILibAsyncSocket_SocketModule module, int timeo
#define ILibAsyncSocket_SetTimeout(module, timeoutSeconds, timeoutHandler) ILibAsyncSocket_SetTimeoutEx(module, timeoutSeconds*1000, timeoutHandler)
#ifndef MICROSTACK_NOTLS
int ILibAsyncSocket_TLS_WasHandshakeError(ILibAsyncSocket_SocketModule socketModule);
X509 *ILibAsyncSocket_SslGetCert(ILibAsyncSocket_SocketModule socketModule);
STACK_OF(X509) *ILibAsyncSocket_SslGetCerts(ILibAsyncSocket_SocketModule socketModule);
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#if defined(WIN32) && !defined(_WIN32_WCE)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
@@ -481,6 +497,56 @@ int __fastcall util_from_cer(char* data, int datalen, struct util_cert* cert)
return ((cert->x509) == NULL);
}
int __fastcall util_from_pkcs7b_string(char *data, int datalen, char *out, int outLen)
{
BIO* bio = BIO_new_mem_buf((void*)data, datalen);
BIO* bio_out = BIO_new(BIO_s_mem());
BUF_MEM *outBuffer;
int retVal = 0, i = 0;
PKCS7 *p7 = NULL;
STACK_OF(X509) *certs = NULL;
STACK_OF(X509_ALGOR) *md_algs = NULL;
STACK_OF(PKCS7_SIGNER_INFO) *sinfo = NULL;
BIO_get_mem_ptr(bio_out, &outBuffer);
p7 = d2i_PKCS7_bio(bio, NULL);
md_algs = p7->d.sign->md_algs;
sinfo = p7->d.sign->signer_info;
for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfo); i++)
{
printf("Hash Algorithm: %s\n", OBJ_nid2ln(OBJ_obj2nid(sk_PKCS7_SIGNER_INFO_value(sinfo, i)->digest_alg->algorithm)));
printf("Enc Algorithm: %s\n", OBJ_nid2ln(OBJ_obj2nid(sk_PKCS7_SIGNER_INFO_value(sinfo, i)->digest_enc_alg->algorithm)));
}
for (i = 0; i < sk_X509_ALGOR_num(md_algs); i++)
{
printf("Algorithm: %s\n", OBJ_nid2ln(OBJ_obj2nid(sk_X509_ALGOR_value(md_algs, i)->algorithm)));
}
certs = p7->d.sign->cert;
for (i = 0; certs && i < sk_X509_num(certs); i++)
{
PEM_write_bio_X509(bio_out, sk_X509_value(certs, i));
}
if (outLen >= (int)outBuffer->length)
{
memcpy_s(out, outLen, outBuffer->data, outBuffer->length);
out[outBuffer->length] = 0;
}
else
{
retVal = (int)(outBuffer->length) + 1;
}
BIO_free(bio);
BIO_free(bio_out);
return(retVal);
}
int __fastcall util_from_pem_string(char *data, int datalen, struct util_cert* cert)
{
BIO* bio = BIO_new_mem_buf((void*)data, datalen);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILIB_CRYPTO__
#define __ILIB_CRYPTO__
@@ -95,6 +111,7 @@ int __fastcall util_to_cer(struct util_cert cert, char** data);
int __fastcall util_from_cer(char* data, int datalen, struct util_cert* cert);
int __fastcall util_from_pem(char* filename, struct util_cert* cert);
int __fastcall util_from_pem_string(char *data, int datalen, struct util_cert* cert);
int __fastcall util_from_pkcs7b_string(char *data, int datalen, char *out, int outLen);
int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, int bits, int days, char* name, enum CERTIFICATE_TYPES certtype, struct util_cert* initialcert);
void __fastcall util_printcert(struct util_cert cert);
void __fastcall util_printcert_pk(struct util_cert cert);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -23,7 +39,7 @@ typedef struct _ILibIPAddressMonitor
#ifdef WIN32
SOCKET mSocket;
DWORD bytesReturned;
WSAOVERLAPPED reserved;
OVERLAPPED *reserved;
#elif defined (_POSIX)
int mSocket;
struct sockaddr_nl addr;
@@ -46,12 +62,16 @@ void CALLBACK ILibIPAddressMonitor_dispatch(
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)lpOverlapped->hEvent;
ILibChain_RunOnMicrostackThread(obj->chainLink.ParentChain, ILibIPAddressMonitor_MicrostackThreadDispatch, obj);
}
else if (lpOverlapped->hEvent == NULL)
{
free(lpOverlapped);
}
}
void ILibIPAddressMonitor_MicrostackThreadDispatch(void *chain, void *user)
{
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)user;
if (obj->onUpdate != NULL) { obj->onUpdate(obj, obj->user); }
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), &(obj->reserved), ILibIPAddressMonitor_dispatch);
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), (LPWSAOVERLAPPED)&(obj->reserved), ILibIPAddressMonitor_dispatch);
}
#endif
@@ -60,7 +80,7 @@ void ILibIPAddressMonitor_Destroy(void *object)
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)object;
#ifdef WIN32
obj->reserved.hEvent = NULL;
obj->reserved->hEvent = NULL;
closesocket(obj->mSocket);
obj->mSocket = INVALID_SOCKET;
#elif defined(_POSIX)
@@ -108,9 +128,10 @@ ILibIPAddressMonitor ILibIPAddressMonitor_Create(void *chain, ILibIPAddressMonit
obj->onUpdate = handler;
obj->user = user;
#ifdef WIN32
obj->reserved.hEvent = (HANDLE)obj;
obj->reserved = ILibMemory_Allocate(sizeof(OVERLAPPED), 0, NULL, NULL);
obj->reserved->hEvent = (HANDLE)obj;
obj->mSocket = socket(AF_INET, SOCK_DGRAM, 0);
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), &(obj->reserved), ILibIPAddressMonitor_dispatch);
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), obj->reserved, ILibIPAddressMonitor_dispatch);
#elif defined (_POSIX)
obj->mSocket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
int flags = fcntl(obj->mSocket, F_GETFL, 0);

View File

@@ -1,3 +1,19 @@
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __ILIBIPADDRESSMONITOR__
#define __ILIBIPADDRESSMONITOR__

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1555,6 +1555,12 @@ void ILibChain_RunOnMicrostackThreadEx(void *chain, ILibChain_StartEvent handler
value[2] = user;
ILibLifeTime_AddEx(ILibGetBaseTimer(chain), value, 0, &ILibChain_RunOnMicrostackThreadSink, &ILibChain_RunOnMicrostackThreadSink);
}
#ifdef WIN32
HANDLE ILibChain_GetMicrostackThreadHandle(void *chain)
{
return(((struct ILibBaseChain*)chain)->MicrostackThreadHandle);
}
#endif
void ILibChain_Safe_Destroy(void *object)
{
@@ -1911,6 +1917,8 @@ ILibExportMethod void ILibChain_EndContinue(void *chain)
ILibForceUnBlockChain(chain);
}
char* g_ILibCrashID = NULL;
#if defined(WIN32)
int ILib_WindowsExceptionFilter(DWORD exceptionCode, void *exceptionInfo, CONTEXT *exceptionContext)
{
@@ -1981,7 +1989,7 @@ void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext)
psym->MaxNameLen = MAX_SYM_NAME;
pimg->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
len = sprintf_s(buffer, sizeof(buffer), "FATAL EXCEPTION @ ");
len = sprintf_s(buffer, sizeof(buffer), "FATAL EXCEPTION [%s] @ ", (g_ILibCrashID!=NULL? g_ILibCrashID:""));
if (SymFromAddr(GetCurrentProcess(), StackFrame.AddrPC.Offset, &tmp, psym))
{
@@ -2027,6 +2035,18 @@ void ILib_POSIX_CrashHandler(int code)
{
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, "** CRASH **\n", 12);
msgLen += 12;
if (g_ILibCrashID != NULL)
{
int idlen = strnlen_s(g_ILibCrashID, 255);
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, "[", 1);
msgLen += 1;
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, g_ILibCrashID, idlen);
msgLen += idlen;
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, "]\n", 2);
msgLen += 2;
}
}
else if (code == 254)
{
@@ -5894,7 +5914,7 @@ void ILibLifeTime_AddEx(void *LifetimeMonitorObject,void *data, int ms, ILibLife
}
// If this notification is sooner than the existing one, replace it.
if (LifeTimeMonitor->NextTriggerTick > ltms->ExpirationTick) LifeTimeMonitor->NextTriggerTick = ltms->ExpirationTick;
if (LifeTimeMonitor->NextTriggerTick > ltms->ExpirationTick || LifeTimeMonitor->NextTriggerTick == -1) LifeTimeMonitor->NextTriggerTick = ltms->ExpirationTick;
ILibLinkedList_UnLock(LifeTimeMonitor->ObjectList);
}
@@ -5972,7 +5992,7 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
// If it is, that means we shouldn't fire this item anymore.
//
ILibLinkedList_Lock(LifeTimeMonitor->Reserved);
removed = ILibLinkedList_Remove_ByData(LifeTimeMonitor->Reserved,node);
removed = ILibLinkedList_Remove_ByData(LifeTimeMonitor->Reserved,((struct LifeTimeMonitorData*)node)->data);
ILibLinkedList_UnLock(LifeTimeMonitor->Reserved);
EVT = (struct LifeTimeMonitorData*)node;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -859,6 +859,9 @@ int ILibIsRunningOnChainThread(void* chain);
void ILibForceUnBlockChain(void *Chain);
void ILibChain_RunOnMicrostackThreadEx(void *chain, ILibChain_StartEvent handler, void *user);
#define ILibChain_RunOnMicrostackThread(chain, handler, user) if(ILibIsRunningOnChainThread(chain)==0){ILibChain_RunOnMicrostackThreadEx(chain, handler, user);}else{handler(chain,user);}
#ifdef WIN32
HANDLE ILibChain_GetMicrostackThreadHandle(void *chain);
#endif
/* \} */
/*! \defgroup SparseArrayGroup Sparse Array
@@ -1279,6 +1282,7 @@ int ILibIsRunningOnChainThread(void* chain);
//
void ILibChain_DebugOffset(char *buffer, int bufferLen, uint64_t addrOffset);
char* ILibChain_Debug(void *chain, char* buffer, int bufferLen);
extern char* g_ILibCrashID;
#if defined(WIN32)
int ILib_WindowsExceptionFilter(DWORD exceptionCode, void *exceptionInfo, CONTEXT *exceptionContext);
void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,12 +1,11 @@
/*
Copyright 2006 - 2017 Intel Corporation
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,11 +1,11 @@
/*
Copyright 2006 - 2017 Intel Corporation
/*
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -727,6 +727,8 @@ typedef struct ILibStun_dTlsSession
char* holdingQueueTail;
ILibLinkedList receiveHoldBuffer;
BIO *writeBIO;
BUF_MEM *writeBIOBuffer;
char* rpacket;
int rpacketptr;
@@ -753,6 +755,7 @@ typedef struct ILibStun_dTlsSession
ILibSCTP_OnSCTPDebug onRTTCalculated;
ILibSCTP_OnSCTPDebug onTSNFloorNotRaised;
ILibSCTP_OnSCTPDebug onRetryPacket;
#endif
unsigned int PARTIAL_BYTES_ACKED;
@@ -845,6 +848,8 @@ unsigned int ILibStun_CRC32(char *buf, int len)
#define ILibWebRTC_DTLS_TO_SCTP_HEARTBEAT_TIMER_OBJECT(d) d
#define ILibWebRTC_DTLS_FROM_SCTP_HEARTBEAT_TIMER_OBJECT(d) ((ILibStun_dTlsSession*)d)
#define ILibWebRTC_STUN_TO_CONNECTIVITY_CHECK_TIMER(s) ((char*)s+1)
#define ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(s) ((char*)s+3)
#define ILibWebRTC_STUN_FROM_PERIODIC_CHECK_TIMER(s) ((ILibStun_Module*)((char*)s-3))
#define ILibWebRTC_STUN_FROM_CONNECTIVITY_CHECK_TIMER(s) ((ILibStun_Module*)((char*)s-1))
int ILibStunClientIndex = -1;
@@ -1134,6 +1139,7 @@ void ILibStun_OnDestroy(void *object)
if (obj->turnUsername != NULL) { free(obj->turnUsername); obj->turnUsername = NULL; }
if (obj->turnPassword != NULL) { free(obj->turnPassword); obj->turnPassword = NULL; }
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(obj));
if (extraClean == 0) return;
#ifdef WIN32
@@ -1147,6 +1153,7 @@ void ILibStun_OnDestroy(void *object)
// Clean up OpenSSL dTLS session
if (obj->dTlsSessions[i] != NULL)
{
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_DTLS_TO_SCTP_HEARTBEAT_TIMER_OBJECT(obj->dTlsSessions[i]));
free(obj->dTlsSessions[i]);
obj->dTlsSessions[i] = NULL;
}
@@ -1655,6 +1662,110 @@ void ILibStun_FireResults(ILibStun_Module *StunModule, ILibStun_Results Result,
if (StunModule->OnResult != NULL) { StunModule->OnResult(StunModule, Result, PublicIP, node); }
}
}
#ifdef _WEBRTCDEBUG
void _DebugSTUN(char *buffer, int bufferLen)
{
char tid[25];
printf(" --> DEBUG Outbound STUN Packet\n");
unsigned short messageType = ntohs(((unsigned short*)buffer)[0]); // Get the message type
//unsigned short messageLength = ntohs(((unsigned short*)buffer)[1]) + 20; // Get the message length
switch (messageType)
{
case STUN_BINDING_REQUEST:
printf("STUN_BINDING_REQUEST");
break;
case STUN_BINDING_RESPONSE:
printf("STUN_BINDING_RESPONSE");
break;
case STUN_BINDING_ERROR_RESPONSE:
printf("STUN_BINDING_ERROR_RESPONSE");
break;
case STUN_SHAREDSECRET_REQUEST:
printf("STUN_SHARED_SECRET_REQUEST");
break;
case STUN_SHAREDSECRET_RESPONSE:
printf("STUN_SHARED_SECRET_RESPONSE");
break;
case STUN_SHAREDSECRET_ERROR_RESPONSE:
printf("STUN_SHARED_SECRET_ERROR_RESPONSE");
break;
case TURN_ALLOCATE:
printf("TURN_ALLOCATE");
break;
case TURN_ALLOCATE_RESPONSE:
printf("TURN_ALLOCATE_RESPONSE");
break;
case TURN_ALLOCATE_ERROR:
printf("TURN_ALLOCATE_ERROR");
break;
case TURN_REFRESH:
printf("TURN_REFRESH");
break;
case TURN_REFRESH_RESPONSE:
printf("TURN_REFRESH_RESPONSE");
break;
case TURN_REFRESH_ERROR:
printf("TURN_REFRESH_ERROR");
break;
case TURN_SEND:
printf("TURN_SEND");
break;
case TURN_DATA:
printf("TURN_DATA");
break;
case TURN_CREATE_PERMISSION:
printf("TURN_CREATE_PERMISSION");
break;
case TURN_CREATE_PERMISSION_RESPONSE:
printf("TURN_CREATE_PERMISSION_RESPONSE");
break;
case TURN_CREATE_PERMISSION_ERROR:
printf("TURN_CREATE_PERMISSION_ERROR");
break;
case TURN_CHANNEL_BIND:
printf("TURN_CHANNEL_BIND");
break;
case TURN_CHANNEL_BIND_RESPONSE:
printf("TURN_CHANNEL_BIND_RESPONSE");
break;
case TURN_CHANNEL_BIND_ERROR:
printf("TURN_CHANNEL_BIND_ERROR");
break;
case TURN_TCP_CONNECT:
printf("TURN_TCP_CONNECT");
break;
case TURN_TCP_CONNECT_RESPONSE:
printf("TURN_TCP_CONNECT_RESPONSE");
break;
case TURN_TCP_CONNECT_ERROR:
printf("TURN_TCP_CONNECT_ERROR");
break;
case TURN_TCP_CONNECTION_BIND:
printf("TURN_TCP_CONNECTION_BIND");
break;
case TURN_TCP_CONNECTION_BIND_RESPONSE:
printf("TURN_TCP_CONNECTION_BIND_RESPONSE");
break;
case TURN_TCP_CONNECTION_BIND_ERROR:
printf("TURN_TCP_CONNECTION_BIND_ERROR");
break;
case TURN_TCP_CONNECTION_ATTEMPT:
printf("TURN_TCP_CONNECTION_ATTEMPT");
break;
default:
printf("UNKNOWN");
break;
}
printf("\n");
util_tohex(buffer + 8, 12, tid);
printf("...TransactionID: %s\n", tid);
printf("\n");
}
#endif
int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct sockaddr_in6 *remoteInterface)
{
@@ -1682,7 +1793,7 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
messageLength = ntohs(((unsigned short*)buffer)[1]) + 20; // Get the message length
// Check the length and magic string
if (messageLength != bufferLength || ntohl(((int*)buffer)[1]) != 0x2112A442) { ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_STUN_ICE, ILibRemoteLogging_Flags_VerbosityLevel_3, "Skipping: Not a STUN Packet (Magic String)"); return 0; }
if (messageLength != bufferLength || ntohl(((int*)buffer)[1]) != 0x2112A442) { ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_STUN_ICE, ILibRemoteLogging_Flags_VerbosityLevel_4, "Skipping: Not a STUN Packet (Magic String)"); return 0; }
memset(&mappedAddress, 0, sizeof(mappedAddress));
memset(&changedAddress, 0, sizeof(changedAddress));
@@ -2048,9 +2159,12 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
((unsigned int*)(rbuffer + 20))[2] = ((struct sockaddr_in*)remoteInterface)->sin_addr.s_addr ^ 0x42A41221; // IPv4 address
rptr += ILibStun_AddMessageIntegrityAttr(rbuffer, rptr, integritykey, 32);
rptr += ILibStun_AddFingerprint(rbuffer, rptr); // Set the length in this function
rptr += ILibStun_AddFingerprint(rbuffer, rptr); // Set the length in this function
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_STUN_ICE, ILibRemoteLogging_Flags_VerbosityLevel_3, "...Sending Response to %s:%u", ILibRemoteLogging_ConvertAddress((struct sockaddr*)remoteInterface), ntohs(remoteInterface->sin6_port));
#ifdef _WEBRTCDEBUG
_DebugSTUN(rbuffer, rptr);
#endif
}
else if ((obj->IceStates[EncodedSlot]->peerHasActiveOffer == 1 && isControlled != 0 &&
ILibNTOHLL(((unsigned long long*)obj->IceStates[EncodedSlot]->tieBreaker)[0]) < tiebreakValue) ||
@@ -2084,12 +2198,13 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
// Send the data in plain text
ILibStun_SendPacket(obj, rbuffer, 0, rptr, remoteInterface, ILibAsyncSocket_MemoryOwnership_USER);
//ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)remoteInterface, rbuffer, rptr, ILibAsyncSocket_MemoryOwnership_USER);
// Send an ICE request back. This is needed to unlock Chrome/Opera inbound port for TLS. Don't do more than ILibSTUN_MaxSlots of these.
if (obj->IceStates[EncodedSlot]->hostcandidates != NULL && obj->IceStates[EncodedSlot]->hostcandidatecount > 0)
{
if (obj->IceStates[EncodedSlot] != NULL && obj->IceStates[EncodedSlot]->requerycount < ILibSTUN_MaxSlots)
if (obj->IceStates[EncodedSlot] != NULL && obj->IceStates[EncodedSlot]->requerycount < ILibSTUN_MaxSlots && obj->IceStates[EncodedSlot]->dtlsSession < 0)
{
char TransactionID[12];
util_random(12, TransactionID);
@@ -2557,7 +2672,7 @@ void ILibStun_ICE_FinalizeConnectivityChecks(void *object)
void ILibStun_PeriodicStunCheckEx(void *obj)
{
ILibStun_PeriodicStunCheck((struct ILibStun_Module*)obj - 3);
ILibStun_PeriodicStunCheck(ILibWebRTC_STUN_FROM_PERIODIC_CHECK_TIMER(obj));
}
void ILibStun_PeriodicStunCheck(struct ILibStun_Module* obj)
@@ -2565,7 +2680,7 @@ void ILibStun_PeriodicStunCheck(struct ILibStun_Module* obj)
int i;
int needRecheck = 0;
ILibLifeTime_Remove(obj->Timer, obj + 3);
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(obj));
for (i = 0; i < ILibSTUN_MaxSlots; ++i)
{
@@ -2580,8 +2695,9 @@ void ILibStun_PeriodicStunCheck(struct ILibStun_Module* obj)
if (needRecheck != 0)
{
ILibLifeTime_Add(obj->Timer,
obj + 3,
ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(obj),
ILibStun_GetNextPeriodicInterval(ILibSTUN_MinNATKeepAliveIntervalSeconds, ILibSTUN_MaxNATKeepAliveIntervalSeconds),
ILibStun_PeriodicStunCheckEx,
NULL);
@@ -2930,27 +3046,27 @@ void ILibORTC_AddRemoteCandidate(void *stunModule, char* localUsername, struct s
ILibTransport_DoneState ILibStun_SendDtls(struct ILibStun_Module *obj, int session, char* buffer, int bufferLength)
{
ILibTransport_DoneState r = ILibTransport_DoneState_ERROR;
char exBuffer[4096];
int j;
if (obj == NULL || session < 0 || session > (ILibSTUN_MaxSlots-1) || obj->dTlsSessions[session] == NULL || SSL_get_state(obj->dTlsSessions[session]->ssl) != TLS_ST_OK) return ILibTransport_DoneState_ERROR;
#ifdef _WEBRTCDEBUG
// Simulated Inbound Packet Loss
if ((obj->lossPercentage) > 0 && ((rand() % 100) >= (100 - obj->lossPercentage))) { return; }
if ((obj->lossPercentage) > 0 && ((rand() % 100) >= (100 - obj->lossPercentage))) { return(ILibTransport_DoneState_COMPLETE); }
#endif
SSL_write(obj->dTlsSessions[session]->ssl, buffer, bufferLength);
while (BIO_ctrl_pending(SSL_get_wbio(obj->dTlsSessions[session]->ssl)) > 0)
if(obj->dTlsSessions[session]->writeBIOBuffer->length > 0)
{
BIO_clear_retry_flags(obj->dTlsSessions[session]->writeBIO); // Klocwork reports this could block, but this is a memory bio, so it will never block.
// Data is pending in the write buffer, send it out
j = BIO_read(SSL_get_wbio(obj->dTlsSessions[session]->ssl), exBuffer, 4096);
if (obj->IceStates[obj->dTlsSessions[session]->iceStateSlot]->useTurn != 0)
{
if ((((int*)ILibMemory_GetExtraMemory(obj->dTlsSessions[session]->remoteInterface, sizeof(struct sockaddr_in6)))[0] & ILibTURN_FLAGS_CHANNEL_DATA) == ILibTURN_FLAGS_CHANNEL_DATA)
{
if (ILibTURN_GetPendingBytesToSend(obj->mTurnClientModule) == 0)
{
r = (ILibTransport_DoneState)ILibTURN_SendChannelData(obj->mTurnClientModule, (unsigned short)session, exBuffer, 0, j);
r = (ILibTransport_DoneState)ILibTURN_SendChannelData(obj->mTurnClientModule, (unsigned short)session, obj->dTlsSessions[session]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[session]->writeBIOBuffer->length);
}
else
{
@@ -2962,7 +3078,7 @@ ILibTransport_DoneState ILibStun_SendDtls(struct ILibStun_Module *obj, int sessi
{
if (ILibTURN_GetPendingBytesToSend(obj->mTurnClientModule) == 0)
{
r = (ILibTransport_DoneState)ILibTURN_SendIndication(obj->mTurnClientModule, obj->dTlsSessions[session]->remoteInterface, exBuffer, 0, j);
r = (ILibTransport_DoneState)ILibTURN_SendIndication(obj->mTurnClientModule, obj->dTlsSessions[session]->remoteInterface, obj->dTlsSessions[session]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[session]->writeBIOBuffer->length);
}
else
{
@@ -2972,13 +3088,15 @@ ILibTransport_DoneState ILibStun_SendDtls(struct ILibStun_Module *obj, int sessi
}
else
{
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, exBuffer, j, ILibAsyncSocket_MemoryOwnership_USER);
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, obj->dTlsSessions[session]->writeBIOBuffer->data, obj->dTlsSessions[session]->writeBIOBuffer->length, ILibAsyncSocket_MemoryOwnership_USER);
}
}
else
{
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, exBuffer, j, ILibAsyncSocket_MemoryOwnership_USER);
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, obj->dTlsSessions[session]->writeBIOBuffer->data, obj->dTlsSessions[session]->writeBIOBuffer->length, ILibAsyncSocket_MemoryOwnership_USER);
}
obj->dTlsSessions[session]->writeBIOBuffer->data += (obj->dTlsSessions[session]->writeBIOBuffer->length);
obj->dTlsSessions[session]->writeBIOBuffer->length = 0;
}
return r;
}
@@ -3153,7 +3271,6 @@ ILibTransport_DoneState ILibStun_SctpSendDataEx(struct ILibStun_Module *obj, int
if (obj->dTlsSessions[session]->T3RTXTIME == 0)
{
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_2, "...Start T3RTX Timer");
// Only set the T3RTX timer if it is not already running
obj->dTlsSessions[session]->T3RTXTIME = rpacket->LastSentTimeStamp;
#ifdef _WEBRTCDEBUG
@@ -3180,7 +3297,7 @@ ILibTransport_DoneState ILibStun_SctpSendDataEx(struct ILibStun_Module *obj, int
#endif
// Send the packet now
if ((flags & 0x03) == 0x03 && obj->dTlsSessions[session]->rpacketptr > 0 && obj->dTlsSessions[session]->rpacketsize > (obj->dTlsSessions[session]->rpacketptr + 16 + datalen + 4))
if ((flags & 0x03) == 0x03 && obj->dTlsSessions[session]->rpacketptr > 0 && obj->dTlsSessions[session]->rpacketsize > (obj->dTlsSessions[session]->rpacketptr + 16 + datalen + 4) && (obj->dTlsSessions[session]->rpacketptr + 16 + datalen + 4) < 1400)
{
int st;
// Merge this data chunk in packet that is going to be sent
@@ -3757,7 +3874,13 @@ void ILibStun_SctpResent(struct ILibStun_dTlsSession *obj)
// 0xFD means this packet is marked as ABANDONED
if(rpacket->PacketGAPCounter != 0xFE && rpacket->PacketGAPCounter != 0xFD)
{
if ((rpacket->LastSentTimeStamp + obj->RTO) > time) { break; } // T3RTX did not expire for this packet
if ((rpacket->LastSentTimeStamp + obj->RTO) > time)
{
#ifdef _WEBRTCDEBUG
if (obj->onT3RTX != NULL) { obj->onT3RTX(obj, "OnT3RTX", -2); } // Debug event informing of the T3RTX timer non-expiration
#endif
break; // T3RTX did not expire for this packet
}
if ((rpacket->Reliability & 0x2000) == 0x2000 && rpacket->PacketResendCounter >= (rpacket->Reliability & 0x1FFF))
{
// Partial-Reliability REXMIT : Exceeded Max Retransmit
@@ -3786,12 +3909,25 @@ void ILibStun_SctpResent(struct ILibStun_dTlsSession *obj)
obj->senderCredits -= rpacket->PacketSize; // Deduct CWND
if (obj->T3RTXTIME == 0)
{
{
// Only set the T3-RTX timer if it's not already running
obj->T3RTXTIME = time;
#ifdef _WEBRTCDEBUG
if (obj->onT3RTX != NULL) { obj->onT3RTX(obj, "OnT3RTX", obj->RTO); } // Debug event informing of the T3RTX timer expiration
#endif
}
ILibStun_SendSctpPacket(obj->parent, obj->sessionId, rpacket->Data - 12, rpacket->PacketSize);
#ifdef _WEBRTCDEBUG
//if (obj->onSendRetry != NULL) { obj->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
if (obj->onSendRetry != NULL) { obj->onSendRetry(obj, "OnSendRetry", ntohl(((unsigned int*)rpacket->Data)[1])); }
if (obj->onRetryPacket != NULL)
{
char *tmp = ILibMemory_AllocateA(rpacket->PacketSize + 14);
sprintf_s(tmp, 14, "OnRetryPacket");
memcpy_s(tmp + 14, rpacket->PacketSize, rpacket->Data - 12, rpacket->PacketSize);
obj->onRetryPacket(obj, tmp, rpacket->PacketSize);
}
#endif
}
else
{
@@ -3822,6 +3958,7 @@ void ILibStun_SctpOnTimeout(void *object)
else
{
// Close the connection
printf("************************************\n");
sem_post(&(obj->Lock));
ILibRemoteLogging_printf(ILibChainGetLogger(obj->Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP Timeout on Session: %d", obj->sessionId);
ILibStun_SctpDisconnect(obj->parent, obj->sessionId);
@@ -4321,7 +4458,8 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "......Responding with Outbound Reset Request");
outRequest = (ILibSCTP_Reconfig_OutgoingSSNResetRequest*)((char*)(&outChunk->reconfigurationParameter) + outOffset); // Ignore Klocwork Error, it's not a problem in this case
outRequest->parameterType = htons(SCTP_RECONFIG_TYPE_OUTGOING_SSN_RESET_REQUEST);
outRequest->parameterLength = htons(16 + 2 * streamCount);
//outRequest->parameterLength = htons(16 + 2 * streamCount);
outRequest->parameterLength = 16 + 2 * streamCount;
outRequest->LastTSN = htonl(o->outtsn - 1);
outRequest->RReqSeqNum = htonl(o->RREQSEQ++);
outRequest->RResSeqNum = htonl(o->RRESSEQ++);
@@ -4551,6 +4689,12 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
o->zeroWindowProbeTime = 0;
o->lastSackTime = (unsigned int)ILibGetUptime();
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP [SACK] Received");
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... TSN = %u", tsn);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... GAP Count = %u", GapAckCount);
if (o->FastRetransmitExitPoint != 0 && tsn >= o->FastRetransmitExitPoint)
{
// We have exited Fast Recovery Mode
@@ -4579,16 +4723,20 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
// This packet that was ACK'ed and was NOT retransmitted, and NO OTHER packets
// were retransmitted since this packet was originally sent
int r = (int)(o->lastSackTime - ((ILibSCTP_RPACKET*)o->pendingQueueHead)->LastSentTimeStamp);
o->RTTVAR = (int)((double)(1 - RTO_BETA) * (double)o->RTTVAR + RTO_BETA * (double)abs(o->SRTT - r));
o->SRTT = (int)((double)(1 - RTO_ALPHA) * (double)o->SRTT + RTO_ALPHA * (double)r);
o->RTO = o->SRTT + 4 * o->RTTVAR;
if (o->RTO < RTO_MIN) { o->RTO = RTO_MIN; }
if (o->RTO > RTO_MAX) { o->RTO = RTO_MAX; }
rttCalculated = 1; // We only need to calculate this once for each packet received
if (r >= 0)
{
o->RTTVAR = (int)((double)(1 - RTO_BETA) * (double)o->RTTVAR + RTO_BETA * (double)abs(o->SRTT - r));
o->SRTT = (int)((double)(1 - RTO_ALPHA) * (double)o->SRTT + RTO_ALPHA * (double)r);
o->RTO = o->SRTT + 4 * o->RTTVAR;
if (o->RTO < RTO_MIN) { o->RTO = RTO_MIN; }
if (o->RTO > RTO_MAX) { o->RTO = RTO_MAX; }
rttCalculated = 1; // We only need to calculate this once for each packet received
#ifdef _WEBRTCDEBUG
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnRTTCalculated", o->SRTT); }
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnRTTCalculated", o->SRTT); }
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnLastSackTime", o->lastSackTime); }
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnLastSentTime", ((ILibSCTP_RPACKET*)o->pendingQueueHead)->LastSentTimeStamp); }
#endif
}
}
}
cumulativeTSNAdvanced += (((ILibSCTP_RPACKET*)o->pendingQueueHead)->PacketSize - (12 + 16));
@@ -4753,7 +4901,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
FastRetryDisabled = 1;
#ifdef _WEBRTCDEBUG
if (o->onSendFastRetry != NULL) { o->onSendFastRetry(o, "OnSendFastRetry", ((unsigned short*)(packet + sizeof(char*)))[0]); }
if (o->onSendFastRetry != NULL) { o->onSendFastRetry(o, "OnSendFastRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
#endif
}
else
@@ -4775,10 +4923,11 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
o->senderCredits -= (rpacket->PacketSize - (12 + 16)); // Update sender credits
o->lastRetransmitTime = o->lastSackTime; // Every time we retransmit, we need to take note of it, for RTT purposes
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP[%d]: Retransmitting/T3RTX Expired", o->sessionId);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP[%d]: Retransmitting/T3RTX Expired", o->sessionId);
ILibStun_SendSctpPacket(obj, session, rpacket->Data - 12, rpacket->PacketSize);
#ifdef _WEBRTCDEBUG
if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(packet + sizeof(char*)))[0]); }
//if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
if (o->onSendRetry != NULL) { o->onSendRetry(o, "OnSendRetry", ntohl(((unsigned int*)rpacket->Data)[1])); }
#endif
}
else
@@ -4799,7 +4948,8 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
ILibStun_SendSctpPacket(obj, session, rpacket->Data - 12, rpacket->PacketSize);
#ifdef _WEBRTCDEBUG
if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(packet + sizeof(char*)))[0]); }
//if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
if (o->onSendRetry != NULL) { o->onSendRetry(o, "OnSendRetry", ntohl(((unsigned int*)rpacket->Data)[1])); }
#endif
}
rpacket->PacketGAPCounter = frt; // Possibly add to the packet gap counter
@@ -5026,7 +5176,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "... UserTSN = %u", o->userTSN);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "... InTSN = %u", o->intsn);
}
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d, exiting processing loop due to PAUSE state", o->sessionId);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d, exiting processing loop due to PAUSE state", o->sessionId);
break;
}
else
@@ -5040,7 +5190,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
{
unsigned int tsnx = ntohl(((ILibSCTP_DataPayload*)ILibLinkedList_GetDataFromNode(rqptr))->TSN);
if (tsnx != o->intsn + 1) break;
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "TSN Moved Forward to: %u", tsnx);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "TSN Moved Forward to: %u", tsnx);
o->intsn = tsnx;
RCTPRCVDEBUG(printf("MOVED TSN to %u\r\n", o->intsn);)
rqptr = ILibLinkedList_GetNextNode(rqptr);
@@ -5081,7 +5231,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
pid = ntohl(payload->ProtocolID);
o->userTSN = o->intsn = tsnx;
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint|ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d Packet: %u Pulled from Holding Queue", o->sessionId, o->userTSN);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d Packet: %u Pulled from Holding Queue", o->sessionId, o->userTSN);
if (ILibSCTP_GetHoldingQueueFlags(ILibLinkedList_GetNode_Head(o->receiveHoldBuffer))->DataPropagated == 0)
{
@@ -5096,7 +5246,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
ILibLinkedList_Remove(ILibLinkedList_GetNode_Head(o->receiveHoldBuffer));
if((o->flags & DTLS_PAUSE_FLAG)==DTLS_PAUSE_FLAG)
{
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP_2: %d, exiting processing loop due to PAUSE state", o->sessionId);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP_2: %d, exiting processing loop due to PAUSE state", o->sessionId);
break;
}
}
@@ -5114,9 +5264,9 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
}
else
{
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP: %d Packet: %u DROPPED, because holding Queue is FULL", o->sessionId, ntohl(data->TSN));
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... UserTSN = %u", o->userTSN);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... InTSN = %u", o->intsn);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP: %d Packet: %u DROPPED, because holding Queue is FULL", o->sessionId, ntohl(data->TSN));
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... UserTSN = %u", o->userTSN);
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... InTSN = %u", o->intsn);
}
}
@@ -5518,10 +5668,11 @@ void ILibStun_InitiateDTLS(struct ILibStun_IceState *IceState, int IceSlot, stru
// Start a new dTLS session
ILibStun_CreateDtlsSession(obj, j, IceSlot, remoteInterface);
// Set up the memory-buffer BIOs
read = BIO_new(BIO_s_mem());
write = BIO_new(BIO_s_mem());
obj->dTlsSessions[j]->writeBIO = write = BIO_new(BIO_s_mem());
BIO_get_mem_ptr(obj->dTlsSessions[j]->writeBIO, &(obj->dTlsSessions[j]->writeBIOBuffer));
BIO_set_mem_eof_return(read, -1);
BIO_set_mem_eof_return(write, -1);
@@ -5823,7 +5974,8 @@ void ILibStun_OnUDP(ILibAsyncUDPSocket_SocketModule socketModule, char* buffer,
// Set up the memory-buffer BIOs
read = BIO_new(BIO_s_mem());
write = BIO_new(BIO_s_mem());
obj->dTlsSessions[j]->writeBIO = write = BIO_new(BIO_s_mem());
BIO_get_mem_ptr(obj->dTlsSessions[j]->writeBIO, &(obj->dTlsSessions[j]->writeBIOBuffer));
BIO_set_mem_eof_return(read, -1);
BIO_set_mem_eof_return(write, -1);
@@ -5941,28 +6093,32 @@ void ILibStun_OnUDP(ILibAsyncUDPSocket_SocketModule socketModule, char* buffer,
if (obj->dTlsSessions[existingSession] != NULL && obj->dTlsSessions[existingSession]->state != 0)
{
sem_wait(&(obj->dTlsSessions[existingSession]->Lock));
while (BIO_ctrl_pending(SSL_get_wbio(obj->dTlsSessions[existingSession]->ssl)) > 0)
if(obj->dTlsSessions[existingSession]->writeBIOBuffer->length > 0)
{
BIO_clear_retry_flags(obj->dTlsSessions[existingSession]->writeBIO); // Klocwork reports this could block, but this is a memory bio, so it will never block.
// Data is pending in the write buffer, send it out
j = BIO_read(SSL_get_wbio(obj->dTlsSessions[existingSession]->ssl), tbuffer, 4096);
if (socketModule == NULL)
{
// Response was from TURN
if (remoteInterface->sin6_family == 0)
{
ILibTURN_SendChannelData(obj->mTurnClientModule, remoteInterface->sin6_port, tbuffer, 0, j);
ILibTURN_SendChannelData(obj->mTurnClientModule, remoteInterface->sin6_port, obj->dTlsSessions[existingSession]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[existingSession]->writeBIOBuffer->length);
}
else
{
ILibTURN_SendIndication(obj->mTurnClientModule, remoteInterface, tbuffer, 0, j);
ILibTURN_SendIndication(obj->mTurnClientModule, remoteInterface, obj->dTlsSessions[existingSession]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[existingSession]->writeBIOBuffer->length);
}
}
else
{
// Response was from a local Socket
ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)remoteInterface, tbuffer, j, ILibAsyncSocket_MemoryOwnership_USER);
ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)remoteInterface, obj->dTlsSessions[existingSession]->writeBIOBuffer->data, obj->dTlsSessions[existingSession]->writeBIOBuffer->length, ILibAsyncSocket_MemoryOwnership_USER);
}
if(obj->dTlsSessions[existingSession]->state == 4) {ILibWebRTC_DTLS_HandshakeDetect(obj, "S ", tbuffer, 0, j);}
if(obj->dTlsSessions[existingSession]->state == 4) {ILibWebRTC_DTLS_HandshakeDetect(obj, "S ", obj->dTlsSessions[existingSession]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[existingSession]->writeBIOBuffer->length);}
obj->dTlsSessions[existingSession]->writeBIOBuffer->data += (obj->dTlsSessions[existingSession]->writeBIOBuffer->length);
obj->dTlsSessions[existingSession]->writeBIOBuffer->length = 0;
}
sem_post(&(obj->dTlsSessions[existingSession]->Lock));
}
@@ -7263,12 +7419,12 @@ int ILibSCTP_Debug_SetDebugCallback(void* dtlsSession, char* debugFieldName, ILi
if (strcmp(debugFieldName, "OnHold") == 0)
{
session->onHold = handler;
handler(session, "OnHold", session->holdingCount);
if (handler != NULL) { handler(session, "OnHold", session->holdingCount); }
}
else if (strcmp(debugFieldName, "OnReceiverCredits") == 0)
{
session->onReceiverCredits = handler;
handler(session, "OnReceiverCredits", session->receiverCredits);
if (handler != NULL) { handler(session, "OnReceiverCredits", session->receiverCredits); }
}
else if (strcmp(debugFieldName, "OnSendFastRetry") == 0)
{
@@ -7281,7 +7437,7 @@ int ILibSCTP_Debug_SetDebugCallback(void* dtlsSession, char* debugFieldName, ILi
else if (strcmp(debugFieldName, "OnCongestionWindowSizeChanged") == 0)
{
session->onCongestionWindowSizeChanged = handler;
handler(session, "OnCongestionWindowSizeChanged", session->congestionWindowSize);
if (handler != NULL) { handler(session, "OnCongestionWindowSizeChanged", session->congestionWindowSize); }
}
else if (strcmp(debugFieldName, "OnSACKReceived") == 0)
{
@@ -7303,6 +7459,10 @@ int ILibSCTP_Debug_SetDebugCallback(void* dtlsSession, char* debugFieldName, ILi
{
session->onTSNFloorNotRaised = handler;
}
else if (strcmp(debugFieldName, "OnRetryPacket") == 0)
{
session->onRetryPacket = handler;
}
else { return 1; }
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006 - 2017 Intel Corporation
Copyright 2006 - 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More