From c1eeba215d7ab8b2bae12514615c32ae3eb09354 Mon Sep 17 00:00:00 2001 From: zaxbbun Date: Sat, 3 Sep 2022 07:19:03 +0800 Subject: [PATCH] Update the return values of socket.listen, also return the real port bind to zero (#1638) --- lualib-src/lua-socket.c | 5 +++-- lualib/skynet/cluster.lua | 4 ++-- lualib/snax/gateserver.lua | 4 ++-- service-src/service_gate.c | 2 +- service/clusterd.lua | 5 +++-- service/gate.lua | 3 ++- skynet-src/skynet_socket.c | 2 +- skynet-src/skynet_socket.h | 2 +- skynet-src/socket_server.c | 19 ++++++++++++++----- skynet-src/socket_server.h | 2 +- 10 files changed, 30 insertions(+), 18 deletions(-) diff --git a/lualib-src/lua-socket.c b/lualib-src/lua-socket.c index c9527372..ea97dce6 100644 --- a/lualib-src/lua-socket.c +++ b/lualib-src/lua-socket.c @@ -488,13 +488,14 @@ llisten(lua_State *L) { int port = luaL_checkinteger(L,2); int backlog = luaL_optinteger(L,3,BACKLOG); 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); if (id < 0) { return luaL_error(L, "Listen error"); } lua_pushinteger(L,id); - return 1; + lua_pushinteger(L,port); + return 2; } static size_t diff --git a/lualib/skynet/cluster.lua b/lualib/skynet/cluster.lua index 8118c2f6..e3437b43 100644 --- a/lualib/skynet/cluster.lua +++ b/lualib/skynet/cluster.lua @@ -77,9 +77,9 @@ end function cluster.open(port) if type(port) == "string" then - skynet.call(clusterd, "lua", "listen", port) + return skynet.call(clusterd, "lua", "listen", port) else - skynet.call(clusterd, "lua", "listen", "0.0.0.0", port) + return skynet.call(clusterd, "lua", "listen", "0.0.0.0", port) end end diff --git a/lualib/snax/gateserver.lua b/lualib/snax/gateserver.lua index 3737f025..a896b587 100644 --- a/lualib/snax/gateserver.lua +++ b/lualib/snax/gateserver.lua @@ -41,10 +41,10 @@ function gateserver.start(handler) maxclient = conf.maxclient or 1024 nodelay = conf.nodelay skynet.error(string.format("Listen on %s:%d", address, port)) - socket = socketdriver.listen(address, port) + socket, port = socketdriver.listen(address, port) socketdriver.start(socket) if handler.open then - return handler.open(source, conf) + return handler.open(source, conf, port) end end diff --git a/service-src/service_gate.c b/service-src/service_gate.c index 35fa3ea6..6481937b 100644 --- a/service-src/service_gate.c +++ b/service-src/service_gate.c @@ -331,7 +331,7 @@ start_listen(struct gate *g, char * listen_addr) { portstr[0] = '\0'; host = listen_addr; } - g->listen_id = skynet_socket_listen(ctx, host, port, BACKLOG); + g->listen_id = skynet_socket_listen(ctx, host, &port, BACKLOG); if (g->listen_id < 0) { return 1; } diff --git a/service/clusterd.lua b/service/clusterd.lua index d9f61cd4..9b2758f0 100644 --- a/service/clusterd.lua +++ b/service/clusterd.lua @@ -148,8 +148,9 @@ function command.listen(source, addr, port) local address = assert(node_address[addr], addr .. " is down") addr, port = string.match(address, "([^:]+):(.*)$") end - skynet.call(gate, "lua", "open", { address = addr, port = port }) - skynet.ret(skynet.pack(nil)) + + local param = { address = addr, port = port } + skynet.ret(skynet.pack(skynet.call(gate, "lua", "open", param))) end function command.sender(source, node) diff --git a/service/gate.lua b/service/gate.lua index d78cdafa..5e530e40 100644 --- a/service/gate.lua +++ b/service/gate.lua @@ -11,8 +11,9 @@ skynet.register_protocol { local handler = {} -function handler.open(source, conf) +function handler.open(source, conf, port) watchdog = conf.watchdog or source + return port end function handler.message(fd, msg, sz) diff --git a/skynet-src/skynet_socket.c b/skynet-src/skynet_socket.c index 7ba7a683..31acafc0 100644 --- a/skynet-src/skynet_socket.c +++ b/skynet-src/skynet_socket.c @@ -127,7 +127,7 @@ skynet_socket_sendbuffer_lowpriority(struct skynet_context *ctx, struct socket_s } int -skynet_socket_listen(struct skynet_context *ctx, const char *host, int port, int backlog) { +skynet_socket_listen(struct skynet_context *ctx, const char *host, int *port, int backlog) { uint32_t source = skynet_context_handle(ctx); return socket_server_listen(SOCKET_SERVER, source, host, port, backlog); } diff --git a/skynet-src/skynet_socket.h b/skynet-src/skynet_socket.h index dd66f834..59aabb86 100644 --- a/skynet-src/skynet_socket.h +++ b/skynet-src/skynet_socket.h @@ -29,7 +29,7 @@ void skynet_socket_updatetime(); int skynet_socket_sendbuffer(struct skynet_context *ctx, struct socket_sendbuffer *buffer); int skynet_socket_sendbuffer_lowpriority(struct skynet_context *ctx, struct socket_sendbuffer *buffer); -int skynet_socket_listen(struct skynet_context *ctx, const char *host, int port, int backlog); +int skynet_socket_listen(struct skynet_context *ctx, const char *host, int *port, int backlog); int skynet_socket_connect(struct skynet_context *ctx, const char *host, int port); int skynet_socket_bind(struct skynet_context *ctx, int fd); void skynet_socket_close(struct skynet_context *ctx, int id); diff --git a/skynet-src/socket_server.c b/skynet-src/socket_server.c index f726593b..b9da6b97 100644 --- a/skynet-src/socket_server.c +++ b/skynet-src/socket_server.c @@ -1936,7 +1936,7 @@ socket_server_shutdown(struct socket_server *ss, uintptr_t opaque, int id) { // return -1 means failed // or return AF_INET or AF_INET6 static int -do_bind(const char *host, int port, int protocol, int *family) { +do_bind(const char *host, int *port, int protocol, int *family) { int fd; int status; int reuse = 1; @@ -1946,7 +1946,7 @@ do_bind(const char *host, int port, int protocol, int *family) { if (host == NULL || host[0] == 0) { host = "0.0.0.0"; // INADDR_ANY } - sprintf(portstr, "%d", port); + sprintf(portstr, "%d", *port); memset( &ai_hints, 0, sizeof( ai_hints ) ); ai_hints.ai_family = AF_UNSPEC; if (protocol == IPPROTO_TCP) { @@ -1973,6 +1973,15 @@ do_bind(const char *host, int port, int protocol, int *family) { if (status != 0) goto _failed; + if (*port == 0) { + union sockaddr_all sa; + socklen_t len = sizeof(sa); + + if (getsockname(fd, (struct sockaddr *)&sa, &len) == 0) { + *port = ntohs((*family == AF_INET) ? sa.v4.sin_port : sa.v6.sin6_port); + } + } + freeaddrinfo( ai_list ); return fd; _failed: @@ -1983,7 +1992,7 @@ _failed_fd: } static int -do_listen(const char * host, int port, int backlog) { +do_listen(const char * host, int *port, int backlog) { int family = 0; int listen_fd = do_bind(host, port, IPPROTO_TCP, &family); if (listen_fd < 0) { @@ -1996,8 +2005,8 @@ do_listen(const char * host, int port, int backlog) { return listen_fd; } -int -socket_server_listen(struct socket_server *ss, uintptr_t opaque, const char * addr, int port, int backlog) { +int +socket_server_listen(struct socket_server *ss, uintptr_t opaque, const char * addr, int *port, int backlog) { int fd = do_listen(addr, port, backlog); if (fd < 0) { return -1; diff --git a/skynet-src/socket_server.h b/skynet-src/socket_server.h index beb628ca..ae47c855 100644 --- a/skynet-src/socket_server.h +++ b/skynet-src/socket_server.h @@ -43,7 +43,7 @@ int socket_server_send(struct socket_server *, struct socket_sendbuffer *buffer) int socket_server_send_lowpriority(struct socket_server *, struct socket_sendbuffer *buffer); // ctrl command below returns id -int socket_server_listen(struct socket_server *, uintptr_t opaque, const char * addr, int port, int backlog); +int socket_server_listen(struct socket_server *, uintptr_t opaque, const char * addr, int *port, int backlog); int socket_server_connect(struct socket_server *, uintptr_t opaque, const char * addr, int port); int socket_server_bind(struct socket_server *, uintptr_t opaque, int fd);