示例#1
0
文件: lua-ext.c 项目: cofyc/alilua
int lua_read_request_body(lua_State *L)
{
    epdata_t *epd = get_epd(L);

    if(!epd) {
        lua_pushnil(L);
        lua_pushstring(L, "miss epd!");
        return 2;
    }

    if(epd->websocket) {
        return 0;
    }

    if(epd->contents) {
        epd->contents = NULL;

        lua_pushlstring(L, epd->headers + epd->_header_length, epd->data_len - epd->_header_length);
        return 1;
    }

    if(!epd->se_ptr || epd->content_length <= epd->data_len - epd->_header_length) {
        lua_pushnil(L);
        lua_pushstring(L, "eof");
        return 2;
    }

    epd->status = STEP_READ;
    serv_status.reading_counts++;
    se_be_read(epd->se_ptr, network_be_read_request_body);

    return lua_yield(L, 0);
}
示例#2
0
void be_connect(void *data, int fd)
{
    printf("connected %s %d\n", (char *)data, fd);
    epdata_t *epd = NULL;
    epd = smp_malloc(sizeof(epdata_t));

    if(!epd) {
        close(fd);
        return;
    }

    epd->fd = fd;
    epd->stime = now;

    epd->se_ptr = se_add(loop_fd, fd, epd);
    epd->timeout_ptr = add_timeout(epd, 1000, timeout_handle);

    epd->out_buf = smp_malloc(1024);
    epd->out_buf_len = sprintf(epd->out_buf,
                               "GET / HTTP/1.1\r\nUser-Agent: curl/7.24.0\r\nHost: www.163.com\r\nAccept: */*\r\n\r\n");
    epd->out_buf_sended = 0;

    se_be_read(epd->se_ptr, client_be_write);
    client_be_write(epd->se_ptr);
}
示例#3
0
static int network_be_accept ( se_ptr_t *ptr )
{
    epdata_t *epd = NULL;
    int acc_trys = 0, client_fd = -1;
    struct sockaddr_in remote_addr;
    int addr_len = sizeof ( struct sockaddr_in );

    while ( acc_trys++ < 3 ) {
        //addr_len = sizeof( struct sockaddr_in );
        client_fd = accept ( server_fd, ( struct sockaddr * ) &remote_addr, &addr_len );

        if ( client_fd < 0 && errno != EAGAIN && errno != EWOULDBLOCK ) {
            break;

        }

        if ( client_fd < 0 ) {
            continue;
        }

        if ( !setnonblocking ( client_fd ) ) {
            close ( client_fd );
            return 0;
        }

        epd = malloc ( sizeof ( epdata_t ) );

        if ( !epd ) {
            close ( client_fd );
            return 0;
        }

        epd->fd = client_fd;
        epd->client_addr = remote_addr.sin_addr;
        epd->stime = now;
        epd->status = STEP_WAIT;
        epd->headers = NULL;
        epd->header_len = 0;
        epd->contents = NULL;
        epd->data_len = 0;
        epd->content_length = -1;
        epd->_header_length = 0;
        epd->keepalive = -1;
        epd->process_timeout = 0;
        epd->iov_buf_count = 0;
        epd->websocket = NULL;

        epd->se_ptr = se_add ( loop_fd, client_fd, epd );
        epd->timeout_ptr = add_timeout ( epd, STEP_WAIT_TIMEOUT, timeout_handle );

        se_be_read ( epd->se_ptr, network_be_read );

        serv_status.active_counts++;
        serv_status.connect_counts++;

        acc_trys = 0;
    }
}
示例#4
0
void free_epd_request ( epdata_t *epd )  /// for keepalive
{
    if ( !epd ) {
        return ;
    }

    if ( epd->headers ) {
        if ( epd->headers != &epd->iov ) {
            free ( epd->headers );
        }

        epd->headers = NULL;
    }

    int i = 0;

    for ( i = 0; i < epd->iov_buf_count; i++ ) {
        free ( epd->iov[i].iov_base );
        epd->iov[i].iov_base = NULL;
    }

    epd->iov_buf_count = 0;

    epd->response_header_length = 0;
    epd->response_content_length = 0;
    epd->iov_buf_count = 0;
    epd->response_buf_sended = 0;

    epd->contents = NULL;
    epd->data_len = 0;
    epd->header_len = 0;
    epd->_header_length = 0;
    epd->content_length = -1;
    epd->process_timeout = 0;
    epd->iov_buf_count = 0;

    if ( !epd->websocket ) {
        se_be_read ( epd->se_ptr, network_be_read );

    } else {
        se_be_read ( epd->se_ptr, websocket_be_read );
    }
}
示例#5
0
文件: worker.c 项目: hopestar/alilua
int _be_ssl_accept(se_ptr_t *ptr)
{
    epdata_t *epd = ptr->data;

    if(!epd) {
        return 0;
    }

    if(!epd->ssl) {
        epd->ssl = SSL_new(ssl_ctx);

        if(epd->ssl == NULL) {
            LOGF(ERR, "SSL_new");
            close_client(epd);
            return 0;
        }

        if(SSL_set_fd(epd->ssl, epd->fd) != 1) {
            SSL_free(epd->ssl);
            epd->ssl = NULL;
            LOGF(ERR, "SSL_set_fd");
            close_client(epd);
            return 0;
        }

        if(ssl_epd_idx > -1) {
            if(SSL_set_ex_data(epd->ssl, ssl_epd_idx, epd) != 1) {
                SSL_free(epd->ssl);
                LOGF(ERR, "SSL_set_ex_data");
                int fd = epd->fd;
                free(epd);
                close(fd);
                return 0;
            }
        }
    }

    int ret = SSL_accept(epd->ssl);

    if(ret != 1) {
        int ssl_err = SSL_get_error(epd->ssl, ret);

        if(ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) {
            close_client(epd);
            return 0;
        }

        return 0;
    }

    se_be_read(epd->se_ptr, network_be_read);
}
示例#6
0
文件: worker.c 项目: MarkTseng/alilua
static void be_accept(int client_fd, struct in_addr client_addr)
{
    int sockaddr_len = sizeof(struct sockaddr);
    struct sockaddr_in addr;
    /* Disable the Nagle (TCP No Delay) algorithm */
    int flag = 1;
    int ret = setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));

    if(ret == -1) {
        LOGF(ERR, "Couldn't setsockopt(TCP_NODELAY)");
    }

    if(!set_nonblocking(client_fd, 1)) {
        close(client_fd);
        return;
    }

    epdata_t *epd = malloc(sizeof(epdata_t));

    if(!epd) {
        close(client_fd);
        return;
    }

    bzero(epd, sizeof(epdata_t));

    epd->L = new_lua_thread(_L);

    if(epd->L) {
        lua_pushlightuserdata(epd->L, epd);
        lua_setglobal(epd->L, "__epd__");
    }

    epd->fd = client_fd;
    epd->client_addr = client_addr;
    getsockname(epd->fd, (struct sockaddr *) &addr, &sockaddr_len);
    epd->server_addr = addr.sin_addr;
    epd->status = STEP_WAIT;
    epd->content_length = -1;
    epd->keepalive = -1;
    epd->response_sendfile_fd = -1;
    epd->timeout_type = 0;
    //epd->start_time = longtime();

    epd->se_ptr = se_add(loop_fd, client_fd, epd);
    epd->timeout_ptr = add_timeout(epd, STEP_WAIT_TIMEOUT, timeout_handle);

    se_be_read(epd->se_ptr, network_be_read);

    serv_status.active_counts++;
    serv_status.connect_counts++;
}
示例#7
0
文件: worker.c 项目: hopestar/alilua
static void be_ssl_accept(int client_fd, struct in_addr client_addr)
{
    if(!set_nonblocking(client_fd, 1)) {
        close(client_fd);
        return;
    }

    epdata_t *epd = malloc(sizeof(epdata_t));

    if(!epd) {
        close(client_fd);
        return;
    }

    bzero(epd, sizeof(epdata_t));

    if(NULL == ssl_ctx) {
        free(epd);
        LOGF(ERR, "ssl ctx not inited");
        close(client_fd);
        return;
    }

    if(ssl_epd_idx == -1) {
        epd->ssl_verify = 1;
    }

    epd->L = new_lua_thread(_L);

    if(epd->L) {
        lua_pushlightuserdata(epd->L, epd);
        lua_setglobal(epd->L, "__epd__");
    }

    epd->fd = client_fd;
    epd->client_addr = client_addr;
    epd->status = STEP_WAIT;
    epd->content_length = -1;
    epd->keepalive = -1;
    epd->response_sendfile_fd = -1;
    //epd->start_time = longtime();

    epd->se_ptr = se_add(loop_fd, client_fd, epd);
    epd->timeout_ptr = add_timeout(epd, STEP_WAIT_TIMEOUT, timeout_handle);

    se_be_read(epd->se_ptr, _be_ssl_accept);

    serv_status.active_counts++;
    serv_status.connect_counts++;
}
示例#8
0
void network_worker ( void *_process_func, int process_count, int process_at )
{
    if ( sizeof ( epdata_t ) != 4096 ) {
        printf ( "warning sizof(epdata_t) = %ld\n", sizeof ( epdata_t ) );    // must be 4096
    }

    signal ( SIGPIPE, SIG_IGN );

    _shm_serv_status = shm_malloc ( sizeof ( serv_status_t ) );

    if ( _shm_serv_status == NULL ) {
        perror ( "shm malloc failed\n" );
        signal ( SIGHUP, SIG_IGN );
        exit ( 1 );
    }

    shm_serv_status = _shm_serv_status->p;
    memcpy ( shm_serv_status, &serv_status, sizeof ( serv_status_t ) );

    process_func = _process_func;

    init_mime_types();

    loop_fd = se_create ( EPD_POOL_SIZE );
    set_loop_fd ( loop_fd, process_count );

    se_ptr_t *se = se_add ( loop_fd, server_fd, NULL );

    se_be_read ( se, network_be_accept );

    while ( 1 ) {

        se_loop ( loop_fd, EPOLL_WAITOUT, without_jobs );

        if ( checkProcessForExit() || has_error_for_exit ) {
            break;
        }
    }
}
示例#9
0
static int client_be_write(se_ptr_t *ptr)
{
    printf("client_be_write\n");
    epdata_t *epd = ptr->data;
    int n = 0;

    while((n = send(epd->fd, epd->out_buf + epd->out_buf_sended,
                    epd->out_buf_len - epd->out_buf_sended, MSG_DONTWAIT)) > 0) {
        epd->out_buf_sended += n;
    }

    printf("send %d\n", n);

    if(epd->out_buf_sended == epd->out_buf_len) {
        se_be_read(epd->se_ptr, client_be_read);

    } else if(n < 0 && NOAGAIN)  {
        close_client(epd);
    }

    return 1;
}
示例#10
0
static void be_accept(int client_fd, struct in_addr client_addr)
{
    if(!set_nonblocking(client_fd, 1)) {
        close(client_fd);
        return;
    }

    epdata_t *epd = NULL;
    epd = smp_malloc(sizeof(epdata_t));

    if(!epd) {
        close(client_fd);
        return;
    }

    epd->fd = client_fd;
    epd->client_addr = client_addr;
    epd->stime = now;

    epd->se_ptr = se_add(loop_fd, client_fd, epd);
    epd->timeout_ptr = add_timeout(epd, 1000, timeout_handle);

    se_be_read(epd->se_ptr, be_read);
}
示例#11
0
static int lua_co_read(lua_State *L)
{
    cosocket_t *c*k = NULL;
    {
        if(!lua_isuserdata(L, 1)) {
            lua_pushnil(L);
            lua_pushstring(L, "Error params!");
            return 2;
        }

        c*k = (cosocket_t *) lua_touserdata(L, 1);

        if((c*k->status != 2 || c*k->fd == -1 || !c*k->ptr) && c*k->total_buf_len < 1) {
            lua_pushnil(L);
            lua_pushfstring(L, "Not connected!");
            return 2;
        }

        if(c*k->inuse == 1) {
            lua_pushnil(L);
            lua_pushstring(L, "socket busy!");
            return 2;
        }

        c*k->L = L;
        c*k->buf_read_len = -1; /// read line

        if(lua_isnumber(L, 2)) {
            c*k->buf_read_len = lua_tonumber(L, 2);

            if(c*k->buf_read_len < 0) {
                c*k->buf_read_len = 0;
                lua_pushnil(L);
                lua_pushstring(L, "Error params!");
                return 2;
            }

        } else {
            if(lua_isstring(L, 2)) {
                if(strcmp("*a", lua_tostring(L, 2)) == 0) {
                    c*k->buf_read_len = -2;    /// read all
                }
            }
        }

        int rt = lua_co_read_(c*k);

        if(rt > 0) {
            return rt; // has buf
        }

        if(c*k->fd == -1) {
            lua_pushnil(L);
            lua_pushstring(L, "Not connected!");
            return 2;
        }

        if(c*k->in_read_action != 1) {
            c*k->in_read_action = 1;
            se_be_read(c*k->ptr, cosocket_be_read);
        }

        c*k->timeout_ptr = add_timeout(c*k, c*k->timeout, timeout_handle);
    }
    c*k->inuse = 1;
    return lua_yield(L, 0);
}
示例#12
0
static int _be_connect(cosocket_t *c*k, int fd, int yielded)
{
    int flag = 1;
    int ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));

    c*k->fd = fd;
    c*k->ptr = se_add(_loop_fd, fd, c*k);

    c*k->status = 2;
    c*k->in_read_action = 0;

    if(c*k->use_ssl) {
        if(c*k->ctx == NULL) {
            c*k->ctx = SSL_CTX_new(SSLv23_client_method());

            if(c*k->ctx == NULL) {
                connection_pool_counter_operate(c*k->pool_key, -1);
                se_delete(c*k->ptr);
                close(c*k->fd);

                c*k->ptr = NULL;
                c*k->fd = -1;
                c*k->status = 0;

                lua_pushnil(c*k->L);
                lua_pushstring(c*k->L, "SSL_CTX_new Error");
                return 2;
            }
        }

        c*k->ssl = SSL_new(c*k->ctx);

        if(c*k->ssl == NULL) {
            connection_pool_counter_operate(c*k->pool_key, -1);
            se_delete(c*k->ptr);
            close(c*k->fd);

            c*k->ptr = NULL;
            c*k->fd = -1;
            c*k->status = 0;

            SSL_CTX_free(c*k->ctx);
            c*k->ctx = NULL;

            lua_pushnil(c*k->L);
            lua_pushstring(c*k->L, "SSL_new Error");
            return 2;
        }

        SSL_set_fd(c*k->ssl, c*k->fd);
        se_be_read(c*k->ptr, cosocket_be_ssl_connected);

        if(SSL_connect(c*k->ssl) == 1) {
            se_be_pri(c*k->ptr, NULL);
            lua_pushboolean(c*k->L, 1);
            c*k->inuse = 0;
            return 1;
        }

        c*k->timeout_ptr = add_timeout(c*k, c*k->timeout, timeout_handle);

        return -2;
    }

    se_be_pri(c*k->ptr, NULL);
    lua_pushboolean(c*k->L, 1);
    c*k->inuse = 0;

    return 1;
}
int add_connection_to_pool(int loop_fd, unsigned long pool_key, int pool_size, se_ptr_t *ptr, void *ssl, void *ctx,
                           char *ssl_pw)
{
    if(pool_key < 0 || !ptr || ptr->fd < 0) {
        return 0;
    }

    int k = pool_key % 64;

    int p = (now / connect_pool_ttl) % 2;

    cosocket_connection_pool_t  *n = NULL, *m = NULL;
    n = connect_pool_p[p][k];

    int keepalive = 1;
    setsockopt(ptr->fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive));
#ifdef linux
    int keepidle = 30;
    int keepinterval = 5;
    int keepcount = 3;
    socklen_t optlen = sizeof(keepidle);
    setsockopt(ptr->fd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepidle , optlen);
    setsockopt(ptr->fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , optlen);
    setsockopt(ptr->fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , optlen);
#endif

    if(n == NULL) {
        m = malloc(sizeof(cosocket_connection_pool_t));

        if(m == NULL) {
            return 0;
        }

        m->z = 0; // recached
        m->ptr = ptr;
        m->pool_key = pool_key;
        m->ssl = ssl;
        m->ssl_pw = ssl_pw;
        m->ctx = ctx;
        m->next = NULL;
        m->uper = NULL;

        connect_pool_p[p][k] = m;

        ptr->data = m;
        n = connect_pool_p[p][k];

        if(se_be_read(ptr, cosocket_be_close) == -1) {
            cosocket_be_close(ptr);
        }

        return 1;

    } else {
        int in_pool = 0;

        while(n != NULL) {
            if(n->pool_key == pool_key) {
                if(in_pool++ >= pool_size) {    /// pool full
                    return 0;
                }
            }

            if(n->next == NULL) {    /// last
                m = malloc(sizeof(cosocket_connection_pool_t));

                if(m == NULL) {
                    return 0;
                }

                m->z = 0; // recached
                m->ptr = ptr;
                m->pool_key = pool_key;
                m->ssl = ssl;
                m->ctx = ctx;
                m->next = NULL;
                m->uper = n;
                //m->fd = fd;
                n->next = m;

                ptr->data = m;

                if(se_be_read(ptr, cosocket_be_close) == -1) {
                    cosocket_be_close(ptr);
                }

                return 1;
            }

            n = (cosocket_connection_pool_t *) n->next;
        }
    }

    return 0;
}