]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
lua/streaming: provide streaming buffer as argument
authorJason Ish <jason.ish@oisf.net>
Mon, 2 Jun 2025 21:47:03 +0000 (15:47 -0600)
committerVictor Julien <victor@inliniac.net>
Wed, 4 Jun 2025 07:39:51 +0000 (09:39 +0200)
When setting up a Lua output script for streaming data, we're
explicitly requesting stream data. Just pass the streaming data as
arguments, rather than requiring the script to make an extra call to
get the stream data.

The streaming data will be passed in the "stream" field of the args
passed to the log function.

Eliminates the SCStreamingBuffer Lua function.

doc/userguide/lua/lua-functions.rst
src/output-lua.c
src/util-lua-common.c
src/util-lua-common.h

index 9f87197670960ed4e9adf4ff58266fc6a4eba1a8..de38f03aed78ab3470fd207f2ae7722043b1ed29 100644 (file)
@@ -236,20 +236,24 @@ In case of HTTP body data, the bodies are unzipped and dechunked if applicable.
       return needs
   end
 
-SCStreamingBuffer
-~~~~~~~~~~~~~~~~~
-
-::
+The streaming data will be provided in the ``args`` to the log
+function within a ``stream`` subtable::
 
   function log(args)
-      -- sb_ts and sb_tc are bools indicating the direction of the data
-      data, sb_open, sb_close, sb_ts, sb_tc = SCStreamingBuffer()
-      if sb_ts then
-        print("->")
-      else
-        print("<-")
-      end
-      hex_dump(data)
+    -- The data (buffer)
+    local data = args["stream"]["data"]
+
+    -- Buffer open?
+    local open = args["stream"]["open"]
+
+    -- Buffer closed?
+    local close = args["stream"]["close"]
+
+    -- To server?
+    local ts = args["stream"]["toserver"]
+
+    -- To client?
+    local tc = args["stream"]["toclient"]
   end
 
 Flow variables
index 7d737ab3f23ff51277b45148baa8ddbac9f4291c..77597220ab0cafb74c4ecfafc7a02a00dbdf050e 100644 (file)
@@ -126,23 +126,37 @@ static int LuaStreamingLogger(ThreadVars *tv, void *thread_data, const Flow *f,
     }
 
     LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data;
+    lua_State *luastate = td->lua_ctx->luastate;
 
     SCMutexLock(&td->lua_ctx->m);
 
-    LuaStateSetThreadVars(td->lua_ctx->luastate, tv);
+    LuaStateSetThreadVars(luastate, tv);
     if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION)
-        LuaStateSetTX(td->lua_ctx->luastate, txptr, tx_id);
-    LuaStateSetFlow(td->lua_ctx->luastate, (Flow *)f);
-    LuaStateSetStreamingBuffer(td->lua_ctx->luastate, &b);
+        LuaStateSetTX(luastate, txptr, tx_id);
+    LuaStateSetFlow(luastate, (Flow *)f);
+    LuaStateSetStreamingBuffer(luastate, &b);
 
     /* prepare data to pass to script */
-    lua_getglobal(td->lua_ctx->luastate, "log");
-    lua_newtable(td->lua_ctx->luastate);
+    lua_getglobal(luastate, "log");
+    lua_newtable(luastate);
 
     if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION)
-        LuaPushTableKeyValueInt(td->lua_ctx->luastate, "tx_id", (int)(tx_id));
+        LuaPushTableKeyValueInt(luastate, "tx_id", (int)(tx_id));
 
-    int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0);
+    /* create the "stream" subtable */
+    lua_pushstring(luastate, "stream");
+    lua_newtable(luastate);
+
+    LuaPushTableKeyValueLString(luastate, "data", (const char *)data, data_len);
+    LuaPushTableKeyValueBoolean(luastate, "open", flags & OUTPUT_STREAMING_FLAG_OPEN);
+    LuaPushTableKeyValueBoolean(luastate, "close", flags & OUTPUT_STREAMING_FLAG_CLOSE);
+    LuaPushTableKeyValueBoolean(luastate, "to_server", flags & OUTPUT_STREAMING_FLAG_TOSERVER);
+    LuaPushTableKeyValueBoolean(luastate, "to_client", flags & OUTPUT_STREAMING_FLAG_TOCLIENT);
+
+    /* set the "stream" subtable into the main args table */
+    lua_settable(luastate, -3);
+
+    int retval = lua_pcall(luastate, 1, 0, 0);
     if (retval != 0) {
         SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1));
     }
index ca9b9915fd69cc9f74710f4e567f2183f2285ed2..9498b9b9f2df1756bf648cab91b8f335952b4d9d 100644 (file)
@@ -63,6 +63,13 @@ void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value)
     lua_settable(luastate, -3);
 }
 
+void LuaPushTableKeyValueBoolean(lua_State *luastate, const char *key, bool value)
+{
+    lua_pushstring(luastate, key);
+    lua_pushboolean(luastate, value);
+    lua_settable(luastate, -3);
+}
+
 /** \brief Push a key plus string value to the stack
  *
  *  If value is NULL, string "(null")" will be put on the stack.
@@ -74,43 +81,22 @@ void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char
     lua_settable(luastate, -3);
 }
 
-void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len)
+/** \brief Push a key plus string value with length to the stack.
+ */
+void LuaPushTableKeyValueLString(
+        lua_State *luastate, const char *key, const char *value, size_t len)
 {
     lua_pushstring(luastate, key);
-    LuaPushStringBuffer(luastate, value, len);
+    lua_pushlstring(luastate, value, len);
     lua_settable(luastate, -3);
 }
 
-/** \internal
- *  \brief fill lua stack with payload
- *  \param luastate the lua state
- *  \param p packet
- *  \retval cnt number of data items placed on the stack
- *
- *  Places: payload (string), open (bool), close (bool), toserver (bool), toclient (bool)
- */
-static int LuaCallbackStreamingBufferPushToStack(lua_State *luastate, const LuaStreamingBuffer *b)
+void LuaPushTableKeyValueArray(
+        lua_State *luastate, const char *key, const uint8_t *value, size_t len)
 {
-    //PrintRawDataFp(stdout, (uint8_t *)b->data, b->data_len);
-    lua_pushlstring (luastate, (const char *)b->data, b->data_len);
-    lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_OPEN));
-    lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_CLOSE));
-    lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_TOSERVER));
-    lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_TOCLIENT));
-    return 5;
-}
-
-/** \internal
- *  \brief Wrapper for getting payload into a lua script
- *  \retval cnt number of items placed on the stack
- */
-static int LuaCallbackStreamingBuffer(lua_State *luastate)
-{
-    const LuaStreamingBuffer *b = LuaStateGetStreamingBuffer(luastate);
-    if (b == NULL)
-        return LuaCallbackError(luastate, "internal error: no buffer");
-
-    return LuaCallbackStreamingBufferPushToStack(luastate, b);
+    lua_pushstring(luastate, key);
+    LuaPushStringBuffer(luastate, value, len);
+    lua_settable(luastate, -3);
 }
 
 /** \internal
@@ -145,10 +131,6 @@ static int LuaCallbackThreadInfo(lua_State *luastate)
 
 int LuaRegisterFunctions(lua_State *luastate)
 {
-    /* registration of the callbacks */
-    lua_pushcfunction(luastate, LuaCallbackStreamingBuffer);
-    lua_setglobal(luastate, "SCStreamingBuffer");
-
     lua_pushcfunction(luastate, LuaCallbackThreadInfo);
     lua_setglobal(luastate, "SCThreadInfo");
     return 0;
index fe90dffe2b66a763e52435274aedfa068be09bd9..ddeca01b48409d307fbe9c7b26166997d7ac3a69 100644 (file)
@@ -31,7 +31,10 @@ int LuaCallbackError(lua_State *luastate, const char *msg);
 const char *LuaGetStringArgument(lua_State *luastate, int argc);
 
 void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value);
+void LuaPushTableKeyValueBoolean(lua_State *luastate, const char *key, bool value);
 void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value);
+void LuaPushTableKeyValueLString(
+        lua_State *luastate, const char *key, const char *value, size_t len);
 void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len);
 
 int LuaRegisterFunctions(lua_State *luastate);