ssl request support sni(Server Name Indication) (#1460)

* ssl support sni(Server Name Indication)

* ssl support sni(Server Name Indication)
This commit is contained in:
colin
2021-08-23 16:54:01 +08:00
committed by GitHub
parent fdc4b35281
commit 6ee8d23ac4
4 changed files with 29 additions and 17 deletions

View File

@@ -358,6 +358,10 @@ lnew_tls(lua_State* L) {
if(strcmp(method, "client") == 0) { if(strcmp(method, "client") == 0) {
_init_client_context(L, tls_p, ctx_p); _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) { }else if(strcmp(method, "server") == 0) {
_init_server_context(L, tls_p, ctx_p); _init_server_context(L, tls_p, ctx_p);
} else { } else {

View File

@@ -35,7 +35,7 @@ local function check_protocol(host)
end end
local SSLCTX_CLIENT = nil local SSLCTX_CLIENT = nil
local function gen_interface(protocol, fd) local function gen_interface(protocol, fd, hostname)
if protocol == "http" then if protocol == "http" then
return { return {
init = nil, init = nil,
@@ -49,7 +49,7 @@ local function gen_interface(protocol, fd)
elseif protocol == "https" then elseif protocol == "https" then
local tls = require "http.tlshelper" local tls = require "http.tlshelper"
SSLCTX_CLIENT = SSLCTX_CLIENT or tls.newctx() 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 { return {
init = tls.init_requestfunc(fd, tls_ctx), init = tls.init_requestfunc(fd, tls_ctx),
close = tls.closefunc(tls_ctx), close = tls.closefunc(tls_ctx),
@@ -67,22 +67,26 @@ function httpc.request(method, host, url, recvheader, header, content)
local protocol local protocol
local timeout = httpc.timeout -- get httpc.timeout before any blocked api local timeout = httpc.timeout -- get httpc.timeout before any blocked api
protocol, host = check_protocol(host) protocol, host = check_protocol(host)
local hostname, port = host:match"([^:]+):?(%d*)$" local hostaddr, port = host:match"([^:]+):?(%d*)$"
if port == "" then if port == "" then
port = protocol=="http" and 80 or protocol=="https" and 443 port = protocol=="http" and 80 or protocol=="https" and 443
else else
port = tonumber(port) port = tonumber(port)
end end
if async_dns and not hostname:match(".*%d+$") then local hostname
hostname = dns.resolve(hostname) if not hostaddr:match(".*%d+$") then
hostname = hostaddr
if async_dns then
hostaddr = dns.resolve(hostname)
end
end end
local fd = socket.connect(hostname, port, timeout) local fd = socket.connect(hostaddr, port, timeout)
if not fd then 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 return
end end
-- print("protocol hostname port", protocol, hostname, port) -- print("protocol hostname port", protocol, hostname, port)
local interface = gen_interface(protocol, fd) local interface = gen_interface(protocol, fd, hostname)
local finish local finish
if timeout then if timeout then
skynet.timeout(timeout, function() skynet.timeout(timeout, function()

View File

@@ -89,8 +89,8 @@ function tlshelper.newctx()
return c.newctx() return c.newctx()
end end
function tlshelper.newtls(method, ssl_ctx) function tlshelper.newtls(method, ssl_ctx, hostname)
return c.newtls(method, ssl_ctx) return c.newtls(method, ssl_ctx, hostname)
end end
return tlshelper return tlshelper

View File

@@ -302,7 +302,7 @@ end
local SSLCTX_CLIENT = nil local SSLCTX_CLIENT = nil
local function _new_client_ws(socket_id, protocol) local function _new_client_ws(socket_id, protocol, hostname)
local obj local obj
if protocol == "ws" then if protocol == "ws" then
obj = { obj = {
@@ -319,7 +319,7 @@ local function _new_client_ws(socket_id, protocol)
elseif protocol == "wss" then elseif protocol == "wss" then
local tls = require "http.tlshelper" local tls = require "http.tlshelper"
SSLCTX_CLIENT = SSLCTX_CLIENT or tls.newctx() 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) local init = tls.init_requestfunc(socket_id, tls_ctx)
init() init()
obj = { obj = {
@@ -435,17 +435,21 @@ function M.connect(url, header, timeout)
end end
assert(host) assert(host)
local host_name, host_port = string.match(host, "^([^:]+):?(%d*)$") local host_addr, host_port = string.match(host, "^([^:]+):?(%d*)$")
assert(host_name and host_port) assert(host_addr and host_port)
if host_port == "" then if host_port == "" then
host_port = protocol == "ws" and 80 or 443 host_port = protocol == "ws" and 80 or 443
end end
local hostname
if not host_addr:match(".*%d+$") then
hostname = host_addr
end
uri = uri == "" and "/" or uri uri = uri == "" and "/" or uri
local socket_id = sockethelper.connect(host_name, host_port, timeout) local socket_id = sockethelper.connect(host_addr, host_port, timeout)
local ws_obj = _new_client_ws(socket_id, protocol) local ws_obj = _new_client_ws(socket_id, protocol, hostname)
ws_obj.addr = host ws_obj.addr = host
write_handshake(ws_obj, host_name, uri, header) write_handshake(ws_obj, host_addr, uri, header)
return socket_id return socket_id
end end