Created
April 28, 2025 01:31
-
-
Save Appla/41091c64e77bc63faa0832e5da0e35b7 to your computer and use it in GitHub Desktop.
Get openresty tcp socket's underlying fd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local type = type | |
local error = error | |
local pcall = pcall | |
local getmetatable = getmetatable | |
local ffi = require "ffi" | |
do | |
--if not pcall(ffi.typeof, "tmp_ngx_http_lua_socket_tcp_upstream_t") then | |
-- | |
--end | |
-- based on nginx 1.27.1 | |
-- @see ngx_connection_t, ngx_peer_connection_t, ngx_http_lua_socket_tcp_upstream_t | |
ffi.cdef [[ | |
typedef struct { | |
intptr_t prefix[3]; | |
int fd; | |
char rest[0]; | |
} tmp_ngx_connection_t; | |
typedef struct { | |
tmp_ngx_connection_t *connection; | |
char rest[0]; | |
} tmp_ngx_peer_connection_t; | |
typedef struct { | |
intptr_t prefix[9]; | |
tmp_ngx_peer_connection_t peer; | |
char rest[0]; | |
} tmp_ngx_http_lua_socket_tcp_upstream_t; | |
]] | |
end | |
local ffi_cast = ffi.cast | |
local C = ffi.C | |
local lua_registry = debug.getregistry() | |
-- C types | |
local ngx_http_lua_socket_tcp_upstream_pct = ffi.typeof("tmp_ngx_http_lua_socket_tcp_upstream_t*") | |
-- constants | |
local SOCKET_CTX_INDEX = 1 | |
local _M = { | |
_VERSION = '0.0.1' | |
} | |
-- @see lua-resty-core/lib/resty/core/socket.lua | |
local function get_tcp_socket(cosocket) | |
local tcp_socket = cosocket[SOCKET_CTX_INDEX] | |
if not tcp_socket then | |
error("socket is never created nor connected") | |
end | |
return tcp_socket | |
end | |
local function get_socket_fd(sock) | |
local ud = get_tcp_socket(sock) | |
local cdata_ref = ffi_cast(ngx_http_lua_socket_tcp_upstream_pct, ud) | |
return cdata_ref.peer.connection.fd | |
end | |
_M.get_fd = function(cosock) | |
-- @note this may not nes | |
if type(cosock) ~= "table" then | |
return nil, "valid cosocket object expected" | |
end | |
return pcall(get_socket_fd, cosock) | |
end | |
_M.verify_cosocket = function(cosock) | |
if type(cosock) ~= "table" or getmetatable(cosock) ~= lua_registry.__tcp_cosocket_mt then | |
return nil, "valid cosocket object expected" | |
end | |
return cosock | |
end | |
return _M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment