mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
more error message for socket, and close listen socket when reach limit of open files. See Issue #339
This commit is contained in:
@@ -101,17 +101,24 @@ function gateserver.start(handler)
|
||||
end
|
||||
|
||||
function MSG.close(fd)
|
||||
if handler.disconnect then
|
||||
handler.disconnect(fd)
|
||||
if fd ~= socket then
|
||||
if handler.disconnect then
|
||||
handler.disconnect(fd)
|
||||
end
|
||||
close_fd(fd)
|
||||
end
|
||||
close_fd(fd)
|
||||
end
|
||||
|
||||
function MSG.error(fd, msg)
|
||||
if handler.error then
|
||||
handler.error(fd, msg)
|
||||
if fd == socket then
|
||||
socketdriver.close(fd)
|
||||
skynet.error(msg)
|
||||
else
|
||||
if handler.error then
|
||||
handler.error(fd, msg)
|
||||
end
|
||||
close_fd(fd)
|
||||
end
|
||||
close_fd(fd)
|
||||
end
|
||||
|
||||
function MSG.warning(fd, size)
|
||||
|
||||
@@ -106,16 +106,17 @@ socket_message[4] = function(id, newid, addr)
|
||||
end
|
||||
|
||||
-- SKYNET_SOCKET_TYPE_ERROR = 5
|
||||
socket_message[5] = function(id)
|
||||
socket_message[5] = function(id, _, err)
|
||||
local s = socket_pool[id]
|
||||
if s == nil then
|
||||
skynet.error("socket: error on unknown", id)
|
||||
skynet.error("socket: error on unknown", id, err)
|
||||
return
|
||||
end
|
||||
if s.connected then
|
||||
skynet.error("socket: error on", id)
|
||||
if s.connected or s.connecting then
|
||||
skynet.error("socket: error on", id, err)
|
||||
end
|
||||
s.connected = false
|
||||
driver.close(id)
|
||||
|
||||
wakeup(s)
|
||||
end
|
||||
@@ -170,6 +171,7 @@ local function connect(id, func)
|
||||
id = id,
|
||||
buffer = newbuffer,
|
||||
connected = false,
|
||||
connecting = true,
|
||||
read_required = false,
|
||||
co = false,
|
||||
callback = func,
|
||||
@@ -177,6 +179,7 @@ local function connect(id, func)
|
||||
}
|
||||
socket_pool[id] = s
|
||||
suspend(s)
|
||||
s.connecting = nil
|
||||
if s.connected then
|
||||
return id
|
||||
else
|
||||
@@ -221,7 +224,7 @@ function socket.close(id)
|
||||
return
|
||||
end
|
||||
if s.connected then
|
||||
driver.close(s.id)
|
||||
driver.close(id)
|
||||
-- notice: call socket.close in __gc should be carefully,
|
||||
-- because skynet.wait never return in __gc, so driver.clear may not be called
|
||||
if s.co then
|
||||
|
||||
@@ -36,7 +36,11 @@ forward_message(int type, bool padding, struct socket_message * result) {
|
||||
size_t sz = sizeof(*sm);
|
||||
if (padding) {
|
||||
if (result->data) {
|
||||
sz += strlen(result->data);
|
||||
size_t msg_sz = strlen(result->data);
|
||||
if (msg_sz > 128) {
|
||||
msg_sz = 128;
|
||||
}
|
||||
sz += msg_sz;
|
||||
} else {
|
||||
result->data = "";
|
||||
}
|
||||
@@ -86,7 +90,7 @@ skynet_socket_poll() {
|
||||
forward_message(SKYNET_SOCKET_TYPE_CONNECT, true, &result);
|
||||
break;
|
||||
case SOCKET_ERROR:
|
||||
forward_message(SKYNET_SOCKET_TYPE_ERROR, false, &result);
|
||||
forward_message(SKYNET_SOCKET_TYPE_ERROR, true, &result);
|
||||
break;
|
||||
case SOCKET_ACCEPT:
|
||||
forward_message(SKYNET_SOCKET_TYPE_ACCEPT, true, &result);
|
||||
|
||||
@@ -408,6 +408,7 @@ open_socket(struct socket_server *ss, struct request_open * request, struct sock
|
||||
|
||||
status = getaddrinfo( request->host, port, &ai_hints, &ai_list );
|
||||
if ( status != 0 ) {
|
||||
result->data = (void *)gai_strerror(status);
|
||||
goto _failed;
|
||||
}
|
||||
int sock= -1;
|
||||
@@ -428,12 +429,14 @@ open_socket(struct socket_server *ss, struct request_open * request, struct sock
|
||||
}
|
||||
|
||||
if (sock < 0) {
|
||||
result->data = strerror(errno);
|
||||
goto _failed;
|
||||
}
|
||||
|
||||
ns = new_fd(ss, id, sock, PROTOCOL_TCP, request->opaque, true);
|
||||
if (ns == NULL) {
|
||||
close(sock);
|
||||
result->data = "reach skynet socket number limit";
|
||||
goto _failed;
|
||||
}
|
||||
|
||||
@@ -762,7 +765,7 @@ _failed:
|
||||
result->opaque = request->opaque;
|
||||
result->id = id;
|
||||
result->ud = 0;
|
||||
result->data = NULL;
|
||||
result->data = "reach skynet socket number limit";
|
||||
ss->slot[HASH_ID(id)].type = SOCKET_TYPE_INVALID;
|
||||
|
||||
return SOCKET_ERROR;
|
||||
@@ -803,7 +806,7 @@ bind_socket(struct socket_server *ss, struct request_bind *request, struct socke
|
||||
result->ud = 0;
|
||||
struct socket *s = new_fd(ss, id, request->fd, PROTOCOL_TCP, request->opaque, true);
|
||||
if (s == NULL) {
|
||||
result->data = NULL;
|
||||
result->data = "reach skynet socket number limit";
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
sp_nonblocking(request->fd);
|
||||
@@ -821,11 +824,13 @@ start_socket(struct socket_server *ss, struct request_start *request, struct soc
|
||||
result->data = NULL;
|
||||
struct socket *s = &ss->slot[HASH_ID(id)];
|
||||
if (s->type == SOCKET_TYPE_INVALID || s->id !=id) {
|
||||
result->data = "invalid socket";
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
if (s->type == SOCKET_TYPE_PACCEPT || s->type == SOCKET_TYPE_PLISTEN) {
|
||||
if (sp_add(ss->event_fd, s->fd, s)) {
|
||||
s->type = SOCKET_TYPE_INVALID;
|
||||
result->data = strerror(errno);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
s->type = (s->type == SOCKET_TYPE_PACCEPT) ? SOCKET_TYPE_CONNECTED : SOCKET_TYPE_LISTEN;
|
||||
@@ -913,7 +918,7 @@ set_udp_address(struct socket_server *ss, struct request_setudp *request, struct
|
||||
result->opaque = s->opaque;
|
||||
result->id = s->id;
|
||||
result->ud = 0;
|
||||
result->data = NULL;
|
||||
result->data = "protocol mismatch";
|
||||
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
@@ -995,6 +1000,7 @@ forward_message_tcp(struct socket_server *ss, struct socket *s, struct socket_me
|
||||
default:
|
||||
// close when error
|
||||
force_close(ss, s, result);
|
||||
result->data = strerror(errno);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
return -1;
|
||||
@@ -1055,6 +1061,7 @@ forward_message_udp(struct socket_server *ss, struct socket *s, struct socket_me
|
||||
default:
|
||||
// close when error
|
||||
force_close(ss, s, result);
|
||||
result->data = strerror(errno);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
return -1;
|
||||
@@ -1088,6 +1095,7 @@ report_connect(struct socket_server *ss, struct socket *s, struct socket_message
|
||||
int code = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &error, &len);
|
||||
if (code < 0 || error) {
|
||||
force_close(ss,s, result);
|
||||
result->data = strerror(errno);
|
||||
return SOCKET_ERROR;
|
||||
} else {
|
||||
s->type = SOCKET_TYPE_CONNECTED;
|
||||
@@ -1111,14 +1119,22 @@ report_connect(struct socket_server *ss, struct socket *s, struct socket_message
|
||||
}
|
||||
}
|
||||
|
||||
// return 0 when failed
|
||||
// return 0 when failed, or -1 when file limit
|
||||
static int
|
||||
report_accept(struct socket_server *ss, struct socket *s, struct socket_message *result) {
|
||||
union sockaddr_all u;
|
||||
socklen_t len = sizeof(u);
|
||||
int client_fd = accept(s->fd, &u.s, &len);
|
||||
if (client_fd < 0) {
|
||||
return 0;
|
||||
if (errno == EMFILE || errno == ENFILE) {
|
||||
result->opaque = s->opaque;
|
||||
result->id = s->id;
|
||||
result->ud = 0;
|
||||
result->data = strerror(errno);
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int id = reserve_id(ss);
|
||||
if (id < 0) {
|
||||
@@ -1203,11 +1219,16 @@ socket_server_poll(struct socket_server *ss, struct socket_message * result, int
|
||||
switch (s->type) {
|
||||
case SOCKET_TYPE_CONNECTING:
|
||||
return report_connect(ss, s, result);
|
||||
case SOCKET_TYPE_LISTEN:
|
||||
if (report_accept(ss, s, result)) {
|
||||
case SOCKET_TYPE_LISTEN: {
|
||||
int ok = report_accept(ss, s, result);
|
||||
if (ok > 0) {
|
||||
return SOCKET_ACCEPT;
|
||||
}
|
||||
} if (ok < 0 ) {
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
// when ok == 0, retry
|
||||
break;
|
||||
}
|
||||
case SOCKET_TYPE_INVALID:
|
||||
fprintf(stderr, "socket-server: invalid socket\n");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user