Skip to content

Instantly share code, notes, and snippets.

@misson20000
Created October 7, 2017 03:35
Show Gist options
  • Save misson20000/82f92209800787fedda758c4333c6c8c to your computer and use it in GitHub Desktop.
Save misson20000/82f92209800787fedda758c4333c6c8c to your computer and use it in GitHub Desktop.
class SocketService {
constructor(session) {
var transferMemorySize = 3*32*1024;//0x1fe0000;
if(!window.tmembufs) { window.tmembufs = []; }
this.buffer = new ArrayBuffer(transferMemorySize);
window.tmembufs.push(this.buffer);
this.tm = sc.svcCreateTransferMemory(this.buffer, 0).assertOk();
var req = sc.ipcMsg(0).sendPid().datau64( // Initialize
32*1024,
32*1024,
16*1024,
16*1024,
0, // pid gets filled in here
transferMemorySize
).copyHandle(this.tm).sendTo(session).assertOk();
this.session = session;
}
cleanup() {
sc.svcCloseHandle(this.tm).assertOk();
}
setErrno(r) {
this.errno = r.data[1];
return r.data[0];
}
socket(domain, type, protocol) {
return this.setErrno(sc.ipcMsg(2).datau32(domain, type, protocol).sendTo(this.session).assertOk());
}
connect(socket, address, address_len) {
if(address_len === undefined) { address_len = address.byteLength; }
return this.setErrno(sc.ipcMsg(14).datau32(socket).aDescriptor(address, address_len).xDescriptor(0,0,0).sendTo(this.session).assertOk());
}
send(socket, buffer, length, flags) {
if(flags === undefined) {
flags = length;
length = buffer.byteLength;
}
return this.setErrno(sc.ipcMsg(10).datau32(socket,flags).aDescriptor(buffer, length, 0).xDescriptor(0,0,0).sendTo(this.session).assertOk());
}
sendTo(socket, message, length, flags, dest_addr, dest_len) {
utils.log("sendto");
return this.setErrno(sc.ipcMsg(11).datau32(socket,flags)
.aDescriptor(message, length, 0)
.aDescriptor(dest_addr, dest_len, 0)
.xDescriptor(0, 0, 0)
.xDescriptor(0, 0, 1).sendTo(this.session).assertOk());
}
close(socket) {
return this.setErrno(sc.ipcMsg(26).datau32(socket).sendTo(this.session).assertOk());
}
recv(socket, buffer, length, flags) {
return this.setErrno(sc.ipcMsg(8).datau32(socket, flags)
.bDescriptor(buffer, length, 0)
.cDescriptor(0, 0, true)
.sendTo(this.session).assertOk());
}
// recvfrom?
accept(socket, address, address_len) {
return this.setErrno(sc.ipcMsg(12).datau32(socket)
.bDescriptor(address, address_len, 0)
.cDescriptor(0, 0, true)
.sendTo(this.session).assertOk()); // discards address_len out
}
bind(socket, address, address_len) {
return this.setErrno(sc.ipcMsg(13).datau32(socket)
.aDescriptor(address, address_len, 0)
.xDescriptor(0, 0, 0)
.sendTo(this.session).assertOk());
}
// untested
getsockname(socket, address, address_len) {
sc.ipcMsg(16).datau32(socket)
.bDescriptor(address, address_len, 0)
.cDescriptor(0, 0, true)
.sendTo(this.session).show();
}
listen(socket, backlog) {
return this.setErrno(sc.ipcMsg(18).datau32(socket, backlog).sendTo(this.session).assertOk());
}
// untested
setsockopt(socket, level, option_name, option_value, option_len) {
return this.setErrno(sc.ipcMsg(21).datau32(socket, level, option_name)
.aDescriptor(option_value, option_len, 0)
.xDescriptor(0, 0, 0)
.sendTo(this.session).assertOk());
}
// untested
shutdown(socket, how) {
return this.setErrno(sc.ipcMsg(22).datau32(socket, how).sendTo(this.session).assertOk());
}
htons(val) {
return (val & 0xFF) << 8 | (val >> 8);
}
ipToU32(ip) {
var parts = ip.split(".").map((part) => parseInt(part));
return (((((parts[3] << 8) | parts[2]) << 8) | parts[1]) << 8) | parts[0];
}
makeAddrInfo(ip, portNumber) {
var ai_addr = new Uint32Array(4);
ai_addr[0] = this.htons(portNumber) << 16 | this.htons(2);
ai_addr[1] = this.ipToU32(ip);
return ai_addr;
}
}
sc.getService("bsd:u", (bsdu) => {
try {
var bsd = new SocketService(bsdu);
var fd = bsd.socket(2,1,6);
if(fd > 0x1000) {
throw new Error("socket " + bsd.errno);
}
utils.log("made socket fd " + fd);
/*
if(bsd.connect(fd, bsd.makeAddrInfo("10.0.0.192", 4444), 16) != 0) {
throw new Error("connect " + bsd.errno);
}
utils.log("connected socket");
var str = "hello, world!";
if(bsd.sendTo(fd, utils.str2ab(str), str.length, 0, bsd.makeAddrInfo("10.0.0.192", 4444), 16) > 0x100) {
throw new Error("send " + bsd.errno);
}*/
var switchAddr = "10.0.0.194";
utils.log("binding...");
if(bsd.bind(fd, bsd.makeAddrInfo(switchAddr, 4444), 16) != 0) {
throw new Error("bind " + bsd.errno);
}
utils.log("listening...");
if(bsd.listen(fd, 20) != 0) {
throw new Error("listen " + bsd.errno);
}
utils.log("accepting...");
var addr = new Uint32Array(4);
var cfd = bsd.accept(fd, addr, addr.byteLength);
utils.log("accept -> " + cfd);
utils.log("receiving...");
var buffer = new ArrayBuffer(512);
var nb = bsd.recv(cfd, buffer, buffer.byteLength, 0);
if(nb > 0x800) {
throw new Error("recv " + bsd.errno);
}
utils.hexdump("r", buffer, nb);
utils.log("closing cfd...");
if(bsd.close(cfd) != 0) {
throw new Error("close " + bsd.errno);
}
utils.log("closing fd...");
if(bsd.close(fd) != 0) {
throw new Error("close " + bsd.errno);
}
} finally {
if(bsd) {
bsd.cleanup();
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment