免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1769 | 回复: 2
打印 上一主题 下一主题

怀疑Lighttpd1.4.18一个bug [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-13 10:25 |只看该作者 |倒序浏览
怀疑Lighttpd1.4.18一个bug

在connections.c文件中connection_handle_fdevent函数的line 3有这么一行:
joblist_append(srv, con);把该链接加入joblist中。
在该函数中还有这么一段:
        if (con->state == CON_STATE_WRITE &&
            !chunkqueue_is_empty(con->write_queue) &&
            con->is_writable) {

                if (-1 == connection_handle_write(srv, con)) {
                        connection_set_state(srv, con, CON_STATE_ERROR);

                        log_error_write(srv, __FILE__, __LINE__, "ds",
                                        con->fd,
                                        "handle write failed.");
                } else if (con->state == CON_STATE_WRITE) {
                        con->write_request_ts = srv->cur_ts;
                }
        }

当当前状态为CON_STATE_WRITE并且输出队列非空,套接字可写时调用connection_handle_write,该函数代码:
static int connection_handle_write(server *srv, connection *con) {
        switch(network_write_chunkqueue(srv, con, con->write_queue)) {
        case 0:
                if (con->file_finished) {
                        connection_set_state(srv, con, CON_STATE_RESPONSE_END);
                        joblist_append(srv, con);
                }
                break;
        case -1: /* error on our side */
                log_error_write(srv, __FILE__, __LINE__, "sd",
                                "connection closed: write failed on fd", con->fd);
                connection_set_state(srv, con, CON_STATE_ERROR);
                joblist_append(srv, con);
                break;
        case -2: /* remote close */
                connection_set_state(srv, con, CON_STATE_ERROR);
                joblist_append(srv, con);
                break;
        case 1:
                con->is_writable = 0;

                /* not finished yet -> WRITE */
                break;
        }

        return 0;
}

再次调用joblist_append(srv, con);

int joblist_append(server *srv, connection *con) {
        if (con->in_joblist) return 0;

        if (srv->joblist->size == 0) {
                srv->joblist->size  = 16;
                srv->joblist->ptr   = malloc(sizeof(*srv->joblist->ptr) * srv->joblist->size);
        } else if (srv->joblist->used == srv->joblist->size) {
                srv->joblist->size += 16;
                srv->joblist->ptr   = realloc(srv->joblist->ptr, sizeof(*srv->joblist->ptr) * srv->joblist->size);
        }

        srv->joblist->ptr[srv->joblist->used++] = con;

        return 0;
}


注意if (con->in_joblist) return 0; 整个项目源代码中并没有对con->in_joblist赋值为非0的地方,所以这个条件一直成立。也就是会有相同的con同时在joblist中。

导致下面这段代码,重复处理了相同的con。

                for (ndx = 0; ndx < srv->joblist->used; ndx++) {
                        connection *con = srv->joblist->ptr[ndx];
                        handler_t r;

                        connection_state_machine(srv, con);

                        switch(r = plugins_call_handle_joblist(srv, con)) {
                        case HANDLER_FINISHED:
                        case HANDLER_GO_ON:
                                break;
                        default:
                                log_error_write(srv, __FILE__, __LINE__, "d", r);
                                break;
                        }

                        con->in_joblist = 0;
                }

论坛徽章:
0
2 [报告]
发表于 2009-01-13 11:22 |只看该作者
哪位看过的讨论一下吧。

论坛徽章:
0
3 [报告]
发表于 2009-01-13 20:11 |只看该作者
re出水面,等待有相同怀疑的坛友讨论。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP