]> hydra-www.ietfng.org Git - acmetensortoys-esp-lua_core/commitdiff
telnetd: switch from fifosock to pipe
authorNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 31 May 2020 18:55:17 +0000 (19:55 +0100)
committerNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 31 May 2020 19:21:22 +0000 (20:21 +0100)
telnetd/telnetd-diag.lua
telnetd/telnetd.lua

index 3d371d768d55d80f2c1fc82fb318465ac7ca2703..4e49b1846c8393b969a7aa37f98d5eafa5559d5a 100644 (file)
@@ -7,8 +7,8 @@ return {
        -- restart in some ticks, so that network callbacks have a chance to fire
        -- first, or else we might crash.  Ick!
   --
-  -- Apparently we need "some" because the fifosock sometimes takes one to do its uncorking
-  -- and the network stack is its own monstrosity.  Either way, probably fine.
+  -- Apparently we need "some" because the pipe and socket sometimes take one to do its
+  -- uncorking and the network stack is its own monstrosity.  Either way, probably fine.
   ["restart"] = function(_,s) tmr.create():alarm(10, tmr.ALARM_SINGLE, node.restart) end,
   ["exec"] = function(l,s)
        local f, err = loadstring(l)
index 148dcc7049aaf55f2cfd3f51b56d542b5c4accdc..a4273364145915423e8ca36bbaff8d168d6c701e 100644 (file)
@@ -1,7 +1,9 @@
--- DEPEND: net ; fifosock
-local self = {}
-self.commands = { ["echo"] = function(r,s) s(r) end }
-function self.tryin(i,ft,nc,ns,...) -- input, function table, no-command, no-space, args
+-- DEPEND: net; pipe
+
+local M = {}
+
+M.commands = { ["echo"] = function(r,s) s(r) end }
+function M.tryin(i,ft,nc,ns,...) -- input, function table, no-command, no-space, args
   local ix = i:find("%f[%s]",1,false)
   if (ix ~= nil) then
     local c, r = i:sub(1,ix-1), i:sub(ix+1); local cf = ft[c]
@@ -9,15 +11,17 @@ function self.tryin(i,ft,nc,ns,...) -- input, function table, no-command, no-spa
   else ns(i,...)
   end
 end
-self.on = { ["conn"] = nil, ["disconn"] = nil }
-local function tryon(e,...) local c = self.on[e]; if c ~= nil then c(...) end end
-function self.rx(tx,input,k)
-  self.tryin(input, self.commands,
+M.on = { ["conn"] = nil, ["disconn"] = nil }
+
+local function tryon(e,...) local c = M.on[e]; if c ~= nil then c(...) end end
+
+function M.rx(tx,input,k)
+  M.tryin(input, M.commands,
     function(c,r)
       if c == "quit" then k(false) else
        local rt = OVL["telnetd-"..c]
        if type(rt) == 'function'
-        then self.tryin(r,rt(),function(c2) tx(c.." "..c2.."?") end, function() tx(c.." ??") end,tx)
+        then M.tryin(r,rt(),function(c2) tx(c.." "..c2.."?") end, function() tx(c.." ??") end,tx)
         else tx(c.."?")
        end
        k(true)
@@ -25,18 +29,70 @@ function self.rx(tx,input,k)
     end,
     function(_) tx("?") k(true) end,tx)
 end
-function self.server(sock_)
-  local fsend = (require "fifosock").wrap(sock_)
+
+-- called with an ESTABLISHED TCP socket
+function M.server(sock)
+
+  -- upval: sock
+  local function opipe_cb(opipe)
+    local resp = opipe:read(1400)
+    if resp and #resp > 0 then sock:send(resp) end
+    return false -- block pipe until onsent_cb
+  end
+
+  -- opipe points at opipe_cb, points at sock.
+  local opipe = pipe.create(opipe_cb)
+  local function opw(s) opipe:write(s) end
+
+  -- upval: opipe, opipe_cb
+  --
+  -- so now sock points at onsent_cb which transitively points back at sock;
+  -- a circularity through the registry.  This must be manually broken, which
+  -- we do in teardown or will happen when net kills off the connection due to
+  -- timeout.
+  local function onsent_cb(sock_)
+    -- sock_ == sock; we're already circular anyway, no reason to use sock_
+    opipe_cb(opipe)
+  end
+
+  local ipipe
+
+  -- upval: ipipe, opipe, tryon
   local function teardown(rawsock)
-    rawsock:on("sent", nil)
-    rawsock:on("receive", nil)
-    rawsock:on("disconnection", nil)
-    tryon("disconn",fsend)
-    fsend=nil
+    if rawsock then
+      rawsock:on("sent", nil)
+      rawsock:on("receive", nil)
+      rawsock:on("disconnection", nil)
+    end
+    tryon("disconn",nil)
+    opipe = nil
+    ipipe = nil
+  end
+
+  -- upval: M, sock, teardown, opw
+  local function ipipe_cb(i)
+    local inp = i:read('\n+')
+    if inp and inp:sub(-1) == "\n"
+     then M.rx(opw, inp,
+                function(c) if c
+                             then opw("\n$ ")
+                             else sock:close() teardown(sock)
+                            end
+                end)
+     elseif inp then i:unread(inp)
+     else return false
+    end
   end
-  sock_:on("receive",function(s_,input) self.rx(fsend,input,function(c) if c then fsend("\n$ ") else s_:close() teardown(s_) end end) end)
-  sock_:on("disconnection",function(s_, x) teardown(s_) end)
-  tryon("conn",fsend)
-  fsend("\n$ ")
+
+  ipipe = pipe.create(ipipe_cb)
+
+  -- upval: ipipe
+  sock:on("receive",function(s_,input) ipipe:write(input) end)
+
+  -- upval: teardown
+  sock:on("disconnection",function(s_, x) teardown(s_) end)
+  tryon("conn", opw)
+  opw("\n$ ")
 end
-return self
+
+return M