mirror of
https://github.com/nginx/nginx.git
synced 2025-07-22 20:38:26 +08:00
r1901, r1902, r2032 merge:
bugfixes in channel: *) avoid endless loop if epoll is used *) use CMSG_LEN(), this fixes an alert "sendmsg() failed (9: Bad file descriptor)" on some 64-bit platforms *) read channel until EAGAIN
This commit is contained in:
parent
22a5d84970
commit
4012d9909c
@ -33,7 +33,7 @@ ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
|
|||||||
msg.msg_control = (caddr_t) &cmsg;
|
msg.msg_control = (caddr_t) &cmsg;
|
||||||
msg.msg_controllen = sizeof(cmsg);
|
msg.msg_controllen = sizeof(cmsg);
|
||||||
|
|
||||||
cmsg.cm.cmsg_len = sizeof(cmsg);
|
cmsg.cm.cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
cmsg.cm.cmsg_level = SOL_SOCKET;
|
cmsg.cm.cmsg_level = SOL_SOCKET;
|
||||||
cmsg.cm.cmsg_type = SCM_RIGHTS;
|
cmsg.cm.cmsg_type = SCM_RIGHTS;
|
||||||
*(int *) CMSG_DATA(&cmsg.cm) = ch->fd;
|
*(int *) CMSG_DATA(&cmsg.cm) = ch->fd;
|
||||||
@ -138,7 +138,7 @@ ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
|
|||||||
|
|
||||||
if (ch->command == NGX_CMD_OPEN_CHANNEL) {
|
if (ch->command == NGX_CMD_OPEN_CHANNEL) {
|
||||||
|
|
||||||
if (cmsg.cm.cmsg_len < (socklen_t) sizeof(cmsg)) {
|
if (cmsg.cm.cmsg_len < (socklen_t) CMSG_LEN(sizeof(int))) {
|
||||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||||
"recvmsg() returned too small ancillary data");
|
"recvmsg() returned too small ancillary data");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
|
@ -48,11 +48,16 @@
|
|||||||
|
|
||||||
#if __FreeBSD_version < 400017
|
#if __FreeBSD_version < 400017
|
||||||
|
|
||||||
/* FreeBSD 3.x has no CMSG_SPACE() at all and has the broken CMSG_DATA() */
|
/*
|
||||||
|
* FreeBSD 3.x has no CMSG_SPACE() and CMSG_LEN() and has the broken CMSG_DATA()
|
||||||
|
*/
|
||||||
|
|
||||||
#undef CMSG_SPACE
|
#undef CMSG_SPACE
|
||||||
#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
|
#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
|
||||||
|
|
||||||
|
#undef CMSG_LEN
|
||||||
|
#define CMSG_LEN(l) (ALIGN(sizeof(struct cmsghdr)) + (l))
|
||||||
|
|
||||||
#undef CMSG_DATA
|
#undef CMSG_DATA
|
||||||
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
|
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
|
||||||
|
|
||||||
|
@ -110,11 +110,16 @@
|
|||||||
|
|
||||||
#include <sys/param.h> /* ALIGN() */
|
#include <sys/param.h> /* ALIGN() */
|
||||||
|
|
||||||
/* FreeBSD 3.x has no CMSG_SPACE() at all and has the broken CMSG_DATA() */
|
/*
|
||||||
|
* FreeBSD 3.x has no CMSG_SPACE() and CMSG_LEN() and has the broken CMSG_DATA()
|
||||||
|
*/
|
||||||
|
|
||||||
#undef CMSG_SPACE
|
#undef CMSG_SPACE
|
||||||
#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
|
#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
|
||||||
|
|
||||||
|
#undef CMSG_LEN
|
||||||
|
#define CMSG_LEN(l) (ALIGN(sizeof(struct cmsghdr)) + (l))
|
||||||
|
|
||||||
#undef CMSG_DATA
|
#undef CMSG_DATA
|
||||||
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
|
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
|
||||||
|
|
||||||
|
@ -1055,65 +1055,74 @@ ngx_channel_handler(ngx_event_t *ev)
|
|||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler");
|
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler");
|
||||||
|
|
||||||
n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
|
for ( ;; ) {
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
|
n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
|
||||||
|
|
||||||
if (n == NGX_ERROR) {
|
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
|
||||||
ngx_close_connection(c);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
|
if (n == NGX_ERROR) {
|
||||||
if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
|
||||||
|
if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
|
||||||
|
ngx_del_conn(c, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_close_connection(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (n == NGX_AGAIN) {
|
if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
|
||||||
return;
|
if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
|
||||||
"channel command: %d", ch.command);
|
|
||||||
|
|
||||||
switch (ch.command) {
|
|
||||||
|
|
||||||
case NGX_CMD_QUIT:
|
|
||||||
ngx_quit = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NGX_CMD_TERMINATE:
|
|
||||||
ngx_terminate = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NGX_CMD_REOPEN:
|
|
||||||
ngx_reopen = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NGX_CMD_OPEN_CHANNEL:
|
|
||||||
|
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
|
||||||
"get channel s:%i pid:%P fd:%d", ch.slot, ch.pid, ch.fd);
|
|
||||||
|
|
||||||
ngx_processes[ch.slot].pid = ch.pid;
|
|
||||||
ngx_processes[ch.slot].channel[0] = ch.fd;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NGX_CMD_CLOSE_CHANNEL:
|
|
||||||
|
|
||||||
ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
|
||||||
"close channel s:%i pid:%P our:%P fd:%d",
|
|
||||||
ch.slot, ch.pid, ngx_processes[ch.slot].pid,
|
|
||||||
ngx_processes[ch.slot].channel[0]);
|
|
||||||
|
|
||||||
if (close(ngx_processes[ch.slot].channel[0]) == -1) {
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
|
|
||||||
"close() channel failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_processes[ch.slot].channel[0] = -1;
|
if (n == NGX_AGAIN) {
|
||||||
break;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
||||||
|
"channel command: %d", ch.command);
|
||||||
|
|
||||||
|
switch (ch.command) {
|
||||||
|
|
||||||
|
case NGX_CMD_QUIT:
|
||||||
|
ngx_quit = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_CMD_TERMINATE:
|
||||||
|
ngx_terminate = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_CMD_REOPEN:
|
||||||
|
ngx_reopen = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_CMD_OPEN_CHANNEL:
|
||||||
|
|
||||||
|
ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
||||||
|
"get channel s:%i pid:%P fd:%d",
|
||||||
|
ch.slot, ch.pid, ch.fd);
|
||||||
|
|
||||||
|
ngx_processes[ch.slot].pid = ch.pid;
|
||||||
|
ngx_processes[ch.slot].channel[0] = ch.fd;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_CMD_CLOSE_CHANNEL:
|
||||||
|
|
||||||
|
ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
||||||
|
"close channel s:%i pid:%P our:%P fd:%d",
|
||||||
|
ch.slot, ch.pid, ngx_processes[ch.slot].pid,
|
||||||
|
ngx_processes[ch.slot].channel[0]);
|
||||||
|
|
||||||
|
if (close(ngx_processes[ch.slot].channel[0]) == -1) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
|
||||||
|
"close() channel failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_processes[ch.slot].channel[0] = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user