From 6ee8d23ac480e37e9d1802cd7bab6f3884c0734d Mon Sep 17 00:00:00 2001 From: colin <124654806@qq.com> Date: Mon, 23 Aug 2021 16:54:01 +0800 Subject: [PATCH] ssl request support sni(Server Name Indication) (#1460) * ssl support sni(Server Name Indication) * ssl support sni(Server Name Indication) --- lualib-src/ltls.c | 4 ++++ lualib/http/httpc.lua | 20 ++++++++++++-------- lualib/http/tlshelper.lua | 4 ++-- lualib/http/websocket.lua | 18 +++++++++++------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lualib-src/ltls.c b/lualib-src/ltls.c index 81bd397b..8c50fdea 100644 --- a/lualib-src/ltls.c +++ b/lualib-src/ltls.c @@ -358,6 +358,10 @@ lnew_tls(lua_State* L) { if(strcmp(method, "client") == 0) { _init_client_context(L, tls_p, ctx_p); + if (!lua_isnoneornil(L, 3)) { + const char* hostname = luaL_checkstring(L, 3); + SSL_set_tlsext_host_name(tls_p->ssl, hostname); + } }else if(strcmp(method, "server") == 0) { _init_server_context(L, tls_p, ctx_p); } else { diff --git a/lualib/http/httpc.lua b/lualib/http/httpc.lua index da4e8b02..936ede47 100644 --- a/lualib/http/httpc.lua +++ b/lualib/http/httpc.lua @@ -35,7 +35,7 @@ local function check_protocol(host) end local SSLCTX_CLIENT = nil -local function gen_interface(protocol, fd) +local function gen_interface(protocol, fd, hostname) if protocol == "http" then return { init = nil, @@ -49,7 +49,7 @@ local function gen_interface(protocol, fd) elseif protocol == "https" then local tls = require "http.tlshelper" SSLCTX_CLIENT = SSLCTX_CLIENT or tls.newctx() - local tls_ctx = tls.newtls("client", SSLCTX_CLIENT) + local tls_ctx = tls.newtls("client", SSLCTX_CLIENT, hostname) return { init = tls.init_requestfunc(fd, tls_ctx), close = tls.closefunc(tls_ctx), @@ -67,22 +67,26 @@ function httpc.request(method, host, url, recvheader, header, content) local protocol local timeout = httpc.timeout -- get httpc.timeout before any blocked api protocol, host = check_protocol(host) - local hostname, port = host:match"([^:]+):?(%d*)$" + local hostaddr, port = host:match"([^:]+):?(%d*)$" if port == "" then port = protocol=="http" and 80 or protocol=="https" and 443 else port = tonumber(port) end - if async_dns and not hostname:match(".*%d+$") then - hostname = dns.resolve(hostname) + local hostname + if not hostaddr:match(".*%d+$") then + hostname = hostaddr + if async_dns then + hostaddr = dns.resolve(hostname) + end end - local fd = socket.connect(hostname, port, timeout) + local fd = socket.connect(hostaddr, port, timeout) if not fd then - error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, hostname, port, timeout)) + error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, hostaddr, port, timeout)) return end -- print("protocol hostname port", protocol, hostname, port) - local interface = gen_interface(protocol, fd) + local interface = gen_interface(protocol, fd, hostname) local finish if timeout then skynet.timeout(timeout, function() diff --git a/lualib/http/tlshelper.lua b/lualib/http/tlshelper.lua index e25b2292..04a15b51 100644 --- a/lualib/http/tlshelper.lua +++ b/lualib/http/tlshelper.lua @@ -89,8 +89,8 @@ function tlshelper.newctx() return c.newctx() end -function tlshelper.newtls(method, ssl_ctx) - return c.newtls(method, ssl_ctx) +function tlshelper.newtls(method, ssl_ctx, hostname) + return c.newtls(method, ssl_ctx, hostname) end return tlshelper \ No newline at end of file diff --git a/lualib/http/websocket.lua b/lualib/http/websocket.lua index 92ac1730..c149bbba 100755 --- a/lualib/http/websocket.lua +++ b/lualib/http/websocket.lua @@ -302,7 +302,7 @@ end local SSLCTX_CLIENT = nil -local function _new_client_ws(socket_id, protocol) +local function _new_client_ws(socket_id, protocol, hostname) local obj if protocol == "ws" then obj = { @@ -319,7 +319,7 @@ local function _new_client_ws(socket_id, protocol) elseif protocol == "wss" then local tls = require "http.tlshelper" SSLCTX_CLIENT = SSLCTX_CLIENT or tls.newctx() - local tls_ctx = tls.newtls("client", SSLCTX_CLIENT) + local tls_ctx = tls.newtls("client", SSLCTX_CLIENT, hostname) local init = tls.init_requestfunc(socket_id, tls_ctx) init() obj = { @@ -435,17 +435,21 @@ function M.connect(url, header, timeout) end assert(host) - local host_name, host_port = string.match(host, "^([^:]+):?(%d*)$") - assert(host_name and host_port) + local host_addr, host_port = string.match(host, "^([^:]+):?(%d*)$") + assert(host_addr and host_port) if host_port == "" then host_port = protocol == "ws" and 80 or 443 end + local hostname + if not host_addr:match(".*%d+$") then + hostname = host_addr + end uri = uri == "" and "/" or uri - local socket_id = sockethelper.connect(host_name, host_port, timeout) - local ws_obj = _new_client_ws(socket_id, protocol) + local socket_id = sockethelper.connect(host_addr, host_port, timeout) + local ws_obj = _new_client_ws(socket_id, protocol, hostname) ws_obj.addr = host - write_handshake(ws_obj, host_name, uri, header) + write_handshake(ws_obj, host_addr, uri, header) return socket_id end