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); }
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); }
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; } }
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 ); } }
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); }
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++; }
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++; }
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; } } }
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; }
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); }
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); }
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; }