mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
fix: httpc支持ipv6 (#2125)
* fix: httpc支持ipv6 * httpc ip:port解析放在c层 * lua-socket.c listen增加ip:port字符串解析, 相关cluster代码修改 #2124 * socketchannel changehost port可置空 * socketchannel changehost恢复port判空 * httpc解析域名加端口号逻辑优化 * 注释中字符串模式内容格式优化 --------- Co-authored-by: zhuyin.zhu <zhuyin.zhu@bytedance.com>
This commit is contained in:
@@ -484,8 +484,14 @@ lshutdown(lua_State *L) {
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
llisten(lua_State *L) {
|
llisten(lua_State *L) {
|
||||||
const char * host = luaL_checkstring(L,1);
|
size_t sz = 0;
|
||||||
int port = luaL_checkinteger(L,2);
|
const char * addr = luaL_checklstring(L, 1, &sz);
|
||||||
|
char tmp[sz];
|
||||||
|
int port = 0;
|
||||||
|
const char * host = address_port(L, tmp, addr, 2, &port);
|
||||||
|
if (port == 0) {
|
||||||
|
return luaL_error(L, "Invalid port");
|
||||||
|
}
|
||||||
int backlog = luaL_optinteger(L,3,BACKLOG);
|
int backlog = luaL_optinteger(L,3,BACKLOG);
|
||||||
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int id = skynet_socket_listen(ctx, host,port,backlog);
|
int id = skynet_socket_listen(ctx, host,port,backlog);
|
||||||
|
|||||||
@@ -68,22 +68,29 @@ end
|
|||||||
local function connect(host, timeout)
|
local function connect(host, timeout)
|
||||||
local protocol
|
local protocol
|
||||||
protocol, host = check_protocol(host)
|
protocol, host = check_protocol(host)
|
||||||
local hostaddr, port = host:match"([^:]+):?(%d*)$"
|
|
||||||
if port == "" then
|
local hostname, port
|
||||||
port = protocol=="http" and 80 or protocol=="https" and 443
|
|
||||||
else
|
|
||||||
port = tonumber(port)
|
|
||||||
end
|
|
||||||
local hostname
|
|
||||||
if not hostaddr:match(".*%d+$") then
|
|
||||||
hostname = hostaddr
|
|
||||||
if async_dns then
|
if async_dns then
|
||||||
hostaddr = dns.resolve(hostname)
|
-- hostname string (ends with ":?%d*") must begin with a substring that doesn't contain colon "[^:]"
|
||||||
|
-- and end with a character that is not a colon or a digit "[^%d%]:]".
|
||||||
|
-- hostname not end with ".", pattern "%." can avoid splitting "127.0.0.1" into "127.0.0." and "1"
|
||||||
|
hostname, port = host:match "^([^:]-[^%d%]:%.]):?(%d*)$"
|
||||||
|
if hostname then
|
||||||
|
local msg
|
||||||
|
host, msg = dns.resolve(hostname)
|
||||||
|
if not host then
|
||||||
|
error(string.format("%s dns resolve failed msg:%s", hostname, msg))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local fd = socket.connect(hostaddr, port, timeout)
|
end
|
||||||
|
|
||||||
|
if port == "" or (port == nil and not host:find ":%d+$") then
|
||||||
|
port = protocol=="http" and 80 or protocol=="https" and 443
|
||||||
|
end
|
||||||
|
|
||||||
|
local fd = socket.connect(host, port, timeout)
|
||||||
if not fd then
|
if not fd then
|
||||||
error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, hostaddr, port, timeout))
|
error(string.format("%s connect error host:%s, port:%s, timeout:%s", protocol, host, port, timeout))
|
||||||
end
|
end
|
||||||
-- print("protocol hostname port", protocol, hostname, port)
|
-- print("protocol hostname port", protocol, hostname, port)
|
||||||
local interface = gen_interface(protocol, fd, hostname)
|
local interface = gen_interface(protocol, fd, hostname)
|
||||||
|
|||||||
@@ -407,11 +407,6 @@ function socket.disconnected(id)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function socket.listen(host, port, backlog)
|
function socket.listen(host, port, backlog)
|
||||||
if port == nil then
|
|
||||||
host, port = string.match(host, "(.+):([^:]+)$")
|
|
||||||
host = host:match("^%[(.-)%]$") or host
|
|
||||||
port = tonumber(port)
|
|
||||||
end
|
|
||||||
local id = driver.listen(host, port, backlog)
|
local id = driver.listen(host, port, backlog)
|
||||||
local s = {
|
local s = {
|
||||||
id = id,
|
id = id,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ socket_channel.error = socket_error
|
|||||||
function socket_channel.channel(desc)
|
function socket_channel.channel(desc)
|
||||||
local c = {
|
local c = {
|
||||||
__host = assert(desc.host),
|
__host = assert(desc.host),
|
||||||
__port = assert(desc.port),
|
__port = desc.port,
|
||||||
__backup = desc.backup,
|
__backup = desc.backup,
|
||||||
__auth = desc.auth,
|
__auth = desc.auth,
|
||||||
__response = desc.response, -- It's for session mode
|
__response = desc.response, -- It's for session mode
|
||||||
@@ -328,7 +328,7 @@ local function connect_once(self)
|
|||||||
self.__overload = true
|
self.__overload = true
|
||||||
overload(true)
|
overload(true)
|
||||||
else
|
else
|
||||||
skynet.error(string.format("WARNING: %d K bytes need to send out (fd = %d %s:%s)", size, id, self.__host, self.__port))
|
skynet.error(string.format("WARNING: %d K bytes need to send out (fd = %d)", size, id), self.__host, self.__port)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -464,7 +464,7 @@ local function block_connect(self, once)
|
|||||||
|
|
||||||
r = check_connection(self)
|
r = check_connection(self)
|
||||||
if r == nil then
|
if r == nil then
|
||||||
skynet.error(string.format("Connect to %s:%d failed (%s)", self.__host, self.__port, err))
|
skynet.error("Connect failed", err, self.__host, self.__port)
|
||||||
error(socket_error)
|
error(socket_error)
|
||||||
else
|
else
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ function gateserver.start(handler)
|
|||||||
function CMD.open( source, conf )
|
function CMD.open( source, conf )
|
||||||
assert(not socket)
|
assert(not socket)
|
||||||
local address = conf.address or "0.0.0.0"
|
local address = conf.address or "0.0.0.0"
|
||||||
local port = assert(conf.port)
|
local port = conf.port
|
||||||
maxclient = conf.maxclient or 1024
|
maxclient = conf.maxclient or 1024
|
||||||
nodelay = conf.nodelay
|
nodelay = conf.nodelay
|
||||||
skynet.error(string.format("Listen on %s:%d", address, port))
|
skynet.error("Listen on", address, port)
|
||||||
socket = socketdriver.listen(address, port, conf.backlog)
|
socket = socketdriver.listen(address, port, conf.backlog)
|
||||||
listen_context.co = coroutine.running()
|
listen_context.co = coroutine.running()
|
||||||
listen_context.fd = socket
|
listen_context.fd = socket
|
||||||
|
|||||||
@@ -39,11 +39,9 @@ local function open_channel(t, key)
|
|||||||
end
|
end
|
||||||
local succ, err, c
|
local succ, err, c
|
||||||
if address then
|
if address then
|
||||||
local host, port = string.match(address, "(.+):([^:]+)$")
|
|
||||||
host = host:match("^%[(.-)%]$") or host
|
|
||||||
c = node_sender[key]
|
c = node_sender[key]
|
||||||
if c == nil then
|
if c == nil then
|
||||||
c = skynet.newservice("clustersender", key, nodename, host, port)
|
c = skynet.newservice("clustersender", key, nodename, address)
|
||||||
if node_sender[key] then
|
if node_sender[key] then
|
||||||
-- double check
|
-- double check
|
||||||
skynet.kill(c)
|
skynet.kill(c)
|
||||||
@@ -53,14 +51,14 @@ local function open_channel(t, key)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
succ = pcall(skynet.call, c, "lua", "changenode", host, port)
|
succ = pcall(skynet.call, c, "lua", "changenode", address)
|
||||||
|
|
||||||
if succ then
|
if succ then
|
||||||
t[key] = c
|
t[key] = c
|
||||||
ct.channel = c
|
ct.channel = c
|
||||||
node_sender_closed[key] = nil
|
node_sender_closed[key] = nil
|
||||||
else
|
else
|
||||||
err = string.format("changenode [%s] (%s:%s) failed", key, host, port)
|
err = string.format("changenode [%s] (%s:%s) failed", key, address)
|
||||||
end
|
end
|
||||||
elseif address == false then
|
elseif address == false then
|
||||||
c = node_sender[key]
|
c = node_sender[key]
|
||||||
@@ -147,11 +145,7 @@ function command.listen(source, addr, port, maxclient)
|
|||||||
local gate = skynet.newservice("gate")
|
local gate = skynet.newservice("gate")
|
||||||
if port == nil then
|
if port == nil then
|
||||||
local address = assert(node_address[addr], addr .. " is down")
|
local address = assert(node_address[addr], addr .. " is down")
|
||||||
addr, port = string.match(address, "(.+):([^:]+)$")
|
skynet.call(gate, "lua", "open", { address = address, port = port, maxclient = maxclient })
|
||||||
addr = addr:match("^%[(.-)%]$") or addr
|
|
||||||
port = tonumber(port)
|
|
||||||
assert(port ~= 0)
|
|
||||||
skynet.call(gate, "lua", "open", { address = addr, port = port, maxclient = maxclient })
|
|
||||||
skynet.ret(skynet.pack(addr, port))
|
skynet.ret(skynet.pack(addr, port))
|
||||||
else
|
else
|
||||||
local realaddr, realport = skynet.call(gate, "lua", "open", { address = addr, port = port, maxclient = maxclient })
|
local realaddr, realport = skynet.call(gate, "lua", "open", { address = addr, port = port, maxclient = maxclient })
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ end
|
|||||||
|
|
||||||
function command.changenode(host, port)
|
function command.changenode(host, port)
|
||||||
if not host then
|
if not host then
|
||||||
skynet.error(string.format("Close cluster sender %s:%d", channel.__host, channel.__port))
|
skynet.error("Close cluster sender", channel.__host, channel.__port)
|
||||||
channel:close()
|
channel:close()
|
||||||
else
|
else
|
||||||
channel:changehost(host, tonumber(port))
|
channel:changehost(host, port)
|
||||||
channel:connect(true)
|
channel:connect(true)
|
||||||
end
|
end
|
||||||
skynet.ret(skynet.pack(nil))
|
skynet.ret(skynet.pack(nil))
|
||||||
|
|||||||
Reference in New Issue
Block a user