102 lines
2.1 KiB
JavaScript
102 lines
2.1 KiB
JavaScript
import "./wasm_exec.js";
|
|
|
|
import ipStackAwait from "./ipstack.js";
|
|
|
|
export const State = {
|
|
NoState: 0,
|
|
InUseOtherUser: 1,
|
|
NeedsLogin: 2,
|
|
NeedsMachineAuth: 3,
|
|
Stopped: 4,
|
|
Starting: 5,
|
|
Running: 6,
|
|
};
|
|
|
|
export async function init() {
|
|
const {IpStack} = await ipStackAwait();
|
|
IpStack.init();
|
|
|
|
const listeners = {
|
|
onstateupdate: () => {},
|
|
onnetmap: () => {},
|
|
onloginurl: () => {},
|
|
}
|
|
|
|
let ipn = null;
|
|
let localIp = null;
|
|
let dnsIp = null;
|
|
|
|
const lazyRunIpn = async () => {
|
|
const wasmUrl = new URL("tailscale.wasm", import.meta.url);
|
|
const go = new window.Go();
|
|
let {instance} = await fetch(wasmUrl).then(x => x.arrayBuffer()).then(x => WebAssembly.instantiate(x,go.importObject));
|
|
go.run(instance);
|
|
|
|
const sessionStateStorage = {
|
|
setState(id, value) {
|
|
window.sessionStorage[`ipn-state-${id}`] = value
|
|
},
|
|
getState(id) {
|
|
return window.sessionStorage[`ipn-state-${id}`] || ""
|
|
},
|
|
}
|
|
ipn = newIPN({
|
|
// Persist IPN state in sessionStorage in development, so that we don't need
|
|
// to re-authorize every time we reload the page.
|
|
//stateStorage: sessionStateStorage,
|
|
});
|
|
|
|
const setupIpStack = () => {
|
|
ipn.tun.onmessage = function(ev) {
|
|
IpStack.input(ev.data)
|
|
};
|
|
IpStack.output(function(p){
|
|
ipn.tun.postMessage(p);
|
|
});
|
|
};
|
|
setupIpStack();
|
|
|
|
ipn.run({
|
|
notifyState: (s) => listeners.onstateupdate(s),
|
|
notifyNetMap: (s) => {
|
|
const netMap = JSON.parse(s);
|
|
listeners.onnetmap(netMap);
|
|
const newLocalIp = netMap.self.addresses[0];
|
|
if (localIp != newLocalIp)
|
|
{
|
|
localIp = newLocalIp;
|
|
IpStack.up({localIp, ipMap: {
|
|
["127.0.0.53"]: dnsIp,
|
|
[dnsIp]: "127.0.0.53",
|
|
}});
|
|
}
|
|
},
|
|
notifyBrowseToURL: (l) => listeners.onloginurl(l),
|
|
});
|
|
|
|
};
|
|
|
|
|
|
return {
|
|
connect: IpStack.connect,
|
|
listen: IpStack.listen,
|
|
bind: IpStack.bind,
|
|
parseIP: IpStack.parseIP,
|
|
up: async (conf) => {
|
|
if (ipn == null) {
|
|
await lazyRunIpn();
|
|
}
|
|
ipn.up(conf);
|
|
localIp = null;
|
|
dnsIp = conf.dnsIp || "127.0.0.53";
|
|
},
|
|
down: () => {
|
|
ipn.down();
|
|
IpStack.down();
|
|
},
|
|
login: () => ipn.login(),
|
|
logout: () => ipn.logout(),
|
|
listeners
|
|
};
|
|
}
|
|
|