tailscale_tun.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import "./wasm_exec.js";
  2. import ipStackAwait from "./ipstack.js";
  3. export async function init({ stateUpdateCb, netMapCb, loginUrlCb })
  4. {
  5. const {IpStack} = await ipStackAwait();
  6. const wasmUrl = new URL("tailscale.wasm", import.meta.url);
  7. const go = new window.Go();
  8. let {instance} = await WebAssembly.instantiateStreaming(fetch(wasmUrl),go.importObject);
  9. go.run(instance);
  10. const State = {
  11. NoState: 0,
  12. InUseOtherUser: 1,
  13. NeedsLogin: 2,
  14. NeedsMachineAuth: 3,
  15. Stopped: 4,
  16. Starting: 5,
  17. Running: 6,
  18. };
  19. const sessionStateStorage = {
  20. setState(id, value) {
  21. window.sessionStorage[`ipn-state-${id}`] = value
  22. },
  23. getState(id) {
  24. return window.sessionStorage[`ipn-state-${id}`] || ""
  25. },
  26. }
  27. const ipn = newIPN({
  28. // Persist IPN state in sessionStorage in development, so that we don't need
  29. // to re-authorize every time we reload the page.
  30. stateStorage: sessionStateStorage,
  31. });
  32. const setupIpStack = () => {
  33. ipn.tun.onmessage = function(ev) {
  34. console.log("received on tun:", ev.data)
  35. IpStack.input(ev.data)
  36. };
  37. IpStack.output(function(p){
  38. console.log("sending from tun:", p)
  39. ipn.tun.postMessage(p);
  40. });
  41. IpStack.init();
  42. };
  43. setupIpStack();
  44. let localIp = null;
  45. let dnsIp = null;
  46. ipn.run({
  47. notifyState: stateUpdateCb,
  48. notifyNetMap: (s) => {
  49. const netMap = JSON.parse(s);
  50. if (netMapCb)
  51. netMapCb(netMap);
  52. const newLocalIp = netMap.self.addresses[0];
  53. if (localIp != newLocalIp)
  54. {
  55. localIp = newLocalIp;
  56. IpStack.up({localIp, ipMap: {
  57. ["127.0.0.53"]: dnsIp,
  58. [dnsIp]: "127.0.0.53",
  59. }});
  60. }
  61. },
  62. notifyBrowseToURL: loginUrlCb,
  63. });
  64. return {
  65. connect: IpStack.connect,
  66. listen: IpStack.listen,
  67. bind: IpStack.bind,
  68. parseIP: IpStack.parseIP,
  69. up: (conf) => {
  70. ipn.up(conf);
  71. localIp = null;
  72. dnsIp = conf.dnsIp || "127.0.0.53";
  73. },
  74. down: () => {
  75. ipn.down();
  76. IpStack.down();
  77. },
  78. login: () => ipn.login(),
  79. logout: () => ipn.logout(),
  80. };
  81. }