static void on_events(handle_t h,int events){ kn_socket *s = (kn_socket*)h; if(h->status == SOCKET_CLOSE) return; do{ h->inloop = 1; if(h->status == SOCKET_LISTENING){ process_accept(s); }else if(h->status == SOCKET_CONNECTING){ process_connect(s,events); }else if(h->status == SOCKET_ESTABLISH){ if(events & EVENT_READ){ process_read(s); if(h->status == SOCKET_CLOSE) break; } if(events & EVENT_WRITE) process_write(s); } h->inloop = 0; }while(0); if(h->status == SOCKET_CLOSE) on_destroy(s); }
static int process_q931(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned char **data, int dataoff, Q931 *q931) { H323_UU_PDU *pdu = &q931->UUIE.h323_uu_pdu; int i; int ret = 0; switch (pdu->h323_message_body.choice) { case eH323_UU_PDU_h323_message_body_setup: ret = process_setup(skb, ct, ctinfo, data, dataoff, &pdu->h323_message_body.setup); break; case eH323_UU_PDU_h323_message_body_callProceeding: ret = process_callproceeding(skb, ct, ctinfo, data, dataoff, &pdu->h323_message_body. callProceeding); break; case eH323_UU_PDU_h323_message_body_connect: ret = process_connect(skb, ct, ctinfo, data, dataoff, &pdu->h323_message_body.connect); break; case eH323_UU_PDU_h323_message_body_alerting: ret = process_alerting(skb, ct, ctinfo, data, dataoff, &pdu->h323_message_body.alerting); break; case eH323_UU_PDU_h323_message_body_facility: ret = process_facility(skb, ct, ctinfo, data, dataoff, &pdu->h323_message_body.facility); break; case eH323_UU_PDU_h323_message_body_progress: ret = process_progress(skb, ct, ctinfo, data, dataoff, &pdu->h323_message_body.progress); break; default: pr_debug("nf_ct_q931: Q.931 signal %d\n", pdu->h323_message_body.choice); break; } if (ret < 0) return -1; if (pdu->options & eH323_UU_PDU_h245Control) { for (i = 0; i < pdu->h245Control.count; i++) { ret = process_h245(skb, ct, ctinfo, data, dataoff, &pdu->h245Control.item[i]); if (ret < 0) return -1; } } return 0; }
int32_t epoll_loop(poller_t n,int32_t ms) { assert(n); if(ms < 0)ms = 0; uint64_t sleep_ms; uint64_t timeout = GetSystemMs64() + (uint64_t)ms; uint64_t current_tick; uint32_t read_event = EV_IN | EPOLLRDHUP | EPOLLERR | EPOLLHUP; int32_t notify = 0; do{ if(!dlist_empty(&n->connecting)) { //check timeout connecting uint64_t l_now = GetSystemMs64(); dlist_check_remove(&n->connecting,check_connect_timeout,(void*)&l_now); } if(!is_active_empty(n)) { struct dlist *actived = get_active_list(n); n->actived_index = (n->actived_index+1)%2; socket_t s; while((s = (socket_t)dlist_pop(actived)) != NULL) { if(Process(s)) putin_active(n,(struct dnode*)s); } } current_tick = GetSystemMs64(); if(is_active_empty(n)) sleep_ms = timeout > current_tick ? timeout - current_tick:0; else sleep_ms = 0; notify = 0; int32_t nfds = _epoll_wait(n->poller_fd,n->events,MAX_SOCKET,(uint32_t)sleep_ms); if(nfds < 0) return -1; int32_t i; for(i = 0 ; i < nfds ; ++i) { if(n->events[i].data.fd == n->pipe_reader) { char buf[1]; read(n->pipe_reader,buf,1); notify = 1; }else{ socket_t sock = (socket_t)n->events[i].data.ptr; if(sock) { if(sock->socket_type == CONNECT){ process_connect(sock); } else if(sock->socket_type == LISTEN){ process_accept(sock); } else{ if(n->events[i].events & read_event) on_read_active(sock); if(n->events[i].events & EPOLLOUT) on_write_active(sock); } } } } current_tick = GetSystemMs64(); }while(notify == 0 && timeout > current_tick); return 0; }
static void *worker_thread_or_server(void *userdata) { int ready, i, n, bufsize = 128 * 1024; void *buf; struct epoll_event ev, *e; unsigned short port = (unsigned short)(int)(long)userdata; int s_listen, new_fd; struct sockaddr_in their_addr; struct sockaddr_in my_addr; socklen_t sin_size; ignore_pipe(); if ((s_listen = socket(AF_INET, SOCK_STREAM, 0)) == -1) { kerror("c:%s, e:%s\n", "socket", strerror(errno)); return NULL; } config_socket(s_listen); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); my_addr.sin_addr.s_addr = INADDR_ANY; memset(my_addr.sin_zero, '\0', sizeof(my_addr.sin_zero)); if (bind(s_listen, (struct sockaddr *) &my_addr, sizeof(my_addr)) == -1) { kerror("c:%s, e:%s\n", "bind", strerror(errno)); return NULL; } if (listen(s_listen, BACKLOG) == -1) { kerror("c:%s, e:%s\n", "listen", strerror(errno)); return NULL; } __g_epoll_fd = epoll_create(__g_epoll_max); memset(&ev, 0, sizeof(ev)); ev.data.fd = s_listen; ev.events = EPOLLIN; epoll_ctl(__g_epoll_fd, EPOLL_CTL_ADD, s_listen, &ev); buf = kmem_alloc(bufsize, char); for (;;) { do ready = epoll_wait(__g_epoll_fd, __g_epoll_events, __g_epoll_max, -1); while ((ready == -1) && (errno == EINTR)); for (i = 0; i < ready; i++) { e = __g_epoll_events + i; if (e->data.fd == s_listen) { sin_size = sizeof(their_addr); if ((new_fd = accept(s_listen, (struct sockaddr *) &their_addr, &sin_size)) == -1) { kerror("c:%s, e:%s\n", "accept", strerror(errno)); continue; } /* FIXME: non-blocking will cause orbatch bang */ /* setnonblocking(new_fd); */ /* XXX: new_fd can be o or w */ if (process_connect(new_fd)) close_connect(new_fd); continue; } else if (!(e->events & EPOLLIN)) { kerror("!!! Not EPOLLIN: event is %08x, fd:%d\n", e->events, e->data.fd); continue; } if ((n = recv(e->data.fd, buf, bufsize, 0)) > 0) { if (do_opt_command(e->data.fd, buf, n)) close_connect(e->data.fd); } else { klog("Remote close socket: %d\n", e->data.fd); close_connect(e->data.fd); } } } kmem_free(buf); close(__g_epoll_fd); __g_epoll_fd = -1; return NULL; }