void hub_uninit(struct hub *hub) { struct peer *ptr = hub->peers; tnt_tun_iface_set_status(&hub->tun, TNT_STATUS_ALL_DOWN); tnt_tun_close(&hub->tun); if (hub->tun.interface) { free(hub->tun.interface); } evutil_closesocket(event_get_fd(hub->levent)); evutil_closesocket(event_get_fd(hub->ievent)); event_free(hub->levent); event_free(hub->ievent); while (ptr) { struct peer *tmp = ptr->next; free(ptr->addr); free(ptr); ptr = tmp; } }
/* * Update SNMP event loop. * * New events are added and some other are removed. This function * should be called every time a SNMP event happens: either when * handling a SNMP packet, a SNMP timeout or when sending a SNMP * packet. This function will keep libevent in sync with NetSNMP. * * @param base The libevent base we are working on. */ static void levent_snmp_update(struct lldpd *cfg) { int maxfd = 0; int block = 1; fd_set fdset; struct timeval timeout; static int howmany = 0; int added = 0, removed = 0, current = 0; struct lldpd_events *snmpfd, *snmpfd_next; /* snmp_select_info() can be tricky to understand. We set `block` to 1 to means that we don't request a timeout. snmp_select_info() will reset `block` to 0 if it wants us to setup a timeout. In this timeout, `snmp_timeout()` should be invoked. Each FD in `fdset` will need to be watched for reading. If one of them become active, `snmp_read()` should be called on it. */ FD_ZERO(&fdset); snmp_select_info(&maxfd, &fdset, &timeout, &block); /* We need to untrack any event whose FD is not in `fdset` anymore */ for (snmpfd = TAILQ_FIRST(levent_snmp_fds(cfg)); snmpfd; snmpfd = snmpfd_next) { snmpfd_next = TAILQ_NEXT(snmpfd, next); if (event_get_fd(snmpfd->ev) >= maxfd || (!FD_ISSET(event_get_fd(snmpfd->ev), &fdset))) { event_free(snmpfd->ev); TAILQ_REMOVE(levent_snmp_fds(cfg), snmpfd, next); free(snmpfd); removed++; } else { FD_CLR(event_get_fd(snmpfd->ev), &fdset); current++; } } /* Invariant: FD in `fdset` are not in list of FD */ for (int fd = 0; fd < maxfd; fd++) { if (FD_ISSET(fd, &fdset)) { levent_snmp_add_fd(cfg, fd); added++; } } current += added; if (howmany != current) { log_debug("event", "added %d events, removed %d events, total of %d events", added, removed, current); howmany = current; } /* If needed, handle timeout */ if (evtimer_add(cfg->g_snmp_timeout, block?NULL:&timeout) == -1) log_warnx("event", "unable to schedule timeout function for SNMP"); }
int32_t kqueue_add( void * arg, struct event * ev ) { struct kevent kev; struct kqueuer * poller = (struct kqueuer *)arg; memset( &kev, 0, sizeof(kev) ); if ( ev->events & EV_READ ) { kev.flags = EV_ADD; kev.udata = (void *)ev; kev.filter = EVFILT_READ; kev.ident = event_get_fd((event_t)ev); #ifdef NOTE_EOF kev.fflags = NOTE_EOF; #endif if ( !(ev->events & EV_PERSIST) ) { kev.flags |= EV_ONESHOT; } if ( kqueue_insert( poller, &kev ) != 0 ) { return -1; } ev->status |= EVSTATUS_X_KQINKERNEL; } if ( ev->events & EV_WRITE ) { kev.flags = EV_ADD; kev.udata = (void *)ev; kev.filter = EVFILT_WRITE; kev.ident = event_get_fd((event_t)ev); if ( !(ev->events & EV_PERSIST) ) { kev.flags |= EV_ONESHOT; } if ( kqueue_insert( poller, &kev ) != 0 ) { return -2; } ev->status |= EVSTATUS_X_KQINKERNEL; } return 0; }
void Listener::on_delete(){ MYDEBUG("delete listener"); event_del(listener); if (this->flags & LEV_OPT_CLOSE_ON_FREE) evutil_closesocket(event_get_fd(this->listener)); event_free(this->listener); }
static evutil_socket_t event_listener_getfd(struct evconnlistener *lev) { struct evconnlistener_event *lev_e = EVUTIL_UPCAST(lev, struct evconnlistener_event, base); return event_get_fd(&lev_e->listener); }
int main() { pipe(pp); struct event_base *base = event_base_new(); evr = event_new(base, pp[0], EV_READ, read_cb, NULL); evw = event_new(base, pp[1], EV_WRITE | EV_TIMEOUT, write_cb, NULL); event_add(evw, NULL); event_add(evr, NULL); struct event_base *outbase; int fdout; event_get_assignment(evw, NULL, &fdout, NULL, NULL, NULL); /* Note fdout. */ outbase = event_get_base(evw); /* outbase == base */ event_callback_fn cb = event_get_callback(evw); assert(write_cb == cb); assert(NULL == event_get_callback_arg(evw)); assert(EV_WRITE|EV_TIMEOUT == event_get_events(evw)); assert(pp[1] == event_get_fd(evw)); assert(event_initialized(evw) == 1); test_num_events(); event_base_dispatch(base); return 0; }
void cmd_tcp_eread(evutil_socket_t fd, short which, void *arg) { extern FILE *honeyd_servicefp; struct tcp_con *con = arg; char line[1024]; int nread; struct command *cmd = &con->cmd; TRACE(fd, nread = read(fd, line, sizeof(line))); if (nread <= 0) { if (cmd->fdwantclose) { /* Stdin is already closed */ cmd_free(&con->cmd); tcp_sendfin(con); } else { /* Now stdin will takes us down */ cmd->fdwantclose = 1; } return; } if (nread == sizeof(line)) nread--; line[nread] = '\0'; honeyd_log_service(honeyd_servicefp, IP_PROTO_TCP, &con->conhdr, line); TRACE(event_get_fd(cmd->peread), event_add(cmd->peread, NULL)); }
static void ss_forward_pkt(redudp_client *client, struct sockaddr * destaddr, void *data, size_t pktlen) { ss_client *ssclient = (void*)(client + 1); ss_instance * ss = (ss_instance *)(client->instance+1); struct sockaddr_in * relayaddr = &client->instance->config.relayaddr; struct msghdr msg; struct iovec io[1]; ssize_t outgoing; int rc; ss_header_ipv4 header; size_t len = 0; size_t fwdlen = 0; void * buff = client->instance->shared_buff; /* build and send header */ // TODO: Better implementation and IPv6 Support header.addr_type = ss_addrtype_ipv4; header.addr = ((struct sockaddr_in *)destaddr)->sin_addr.s_addr; header.port = ((struct sockaddr_in *)destaddr)->sin_port; if (enc_ctx_init(&ss->info, &ss->e_ctx, 1)) { redudp_log_error(client, LOG_ERR, "Shadowsocks UDP failed to initialize encryption context."); return; } rc = ss_encrypt(&ss->e_ctx, (char *)&header, sizeof(header), buff, &len); if (rc) { if (len + pktlen < MAX_UDP_PACKET_SIZE) rc = ss_encrypt(&ss->e_ctx, (char *)data, pktlen, buff+len, &fwdlen); else rc = 0; } enc_ctx_free(&ss->e_ctx); if (!rc) { redudp_log_error(client, LOG_DEBUG, "Can't encrypt packet, dropping it"); return; } fwdlen += len; memset(&msg, 0, sizeof(msg)); msg.msg_name = relayaddr; msg.msg_namelen = sizeof(*relayaddr); msg.msg_iov = io; msg.msg_iovlen = SIZEOF_ARRAY(io); io[0].iov_base = buff; io[0].iov_len = fwdlen; outgoing = sendmsg(event_get_fd(&ssclient->udprelay), &msg, 0); if (outgoing == -1) { redudp_log_errno(client, LOG_DEBUG, "sendmsg: Can't forward packet, dropping it"); return; } else if (outgoing != fwdlen) { redudp_log_error(client, LOG_DEBUG, "sendmsg: I was sending %zd bytes, but only %zd were sent.", fwdlen, outgoing); return; } }
static void ev_watch_update(AvahiWatch *w, AvahiWatchEvent a_events) { if (w->ev) event_del(w->ev); _ev_watch_add(w, (int)event_get_fd(w->ev), a_events); }
int32_t kqueue_del( void * arg, struct event * ev ) { struct kevent kev; struct kqueuer * poller = (struct kqueuer *)arg; if ( !(ev->status & EVSTATUS_X_KQINKERNEL) ) { // // 该事件已经不在KQUEUE中了, 直接返回成功 // return 0; } memset( &kev, 0, sizeof(kev) ); if ( ev->events & EV_READ ) { kev.flags = EV_DELETE; kev.filter = EVFILT_READ; kev.ident = event_get_fd((event_t)ev); if ( kqueue_insert( poller, &kev ) != 0 ) { return -2; } ev->status &= ~EVSTATUS_X_KQINKERNEL; } if ( ev->events & EV_WRITE ) { kev.flags = EV_DELETE; kev.filter = EVFILT_WRITE; kev.ident = event_get_fd((event_t)ev); if ( kqueue_insert( poller, &kev ) != 0 ) { return -3; } ev->status &= ~EVSTATUS_X_KQINKERNEL; } return 0; }
static void ss_client_fini(redudp_client *client) { ss_client *ssclient = (void*)(client + 1); if (event_initialized(&ssclient->udprelay)) { close(event_get_fd(&ssclient->udprelay)); if (event_del(&ssclient->udprelay) == -1) redudp_log_errno(client, LOG_ERR, "event_del"); } }
static void event_listener_destroy(struct evconnlistener *lev) { struct evconnlistener_event *lev_e = EVUTIL_UPCAST(lev, struct evconnlistener_event, base); event_del(&lev_e->listener); if (lev->flags & LEV_OPT_CLOSE_ON_FREE) evutil_closesocket(event_get_fd(&lev_e->listener)); event_debug_unassign(&lev_e->listener); }
static void be_socket_destruct(struct bufferevent *bufev) { struct bufferevent_private *bufev_p = EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); evutil_socket_t fd; EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket); fd = event_get_fd(&bufev->ev_read); if ((bufev_p->options & BEV_OPT_CLOSE_ON_FREE) && fd >= 0) EVUTIL_CLOSESOCKET(fd); }
static void ss_pkt_from_server(int fd, short what, void *_arg) { redudp_client *client = _arg; ss_client *ssclient = (void*)(client + 1); ss_instance * ss = (ss_instance *)(client->instance+1); ss_header_ipv4 * header; ssize_t pktlen; size_t fwdlen; struct sockaddr_in udprelayaddr; int rc; void * buff = client->instance->shared_buff; void * buff2 = ss->buff; assert(fd == event_get_fd(&ssclient->udprelay)); pktlen = red_recv_udp_pkt(fd, buff, MAX_UDP_PACKET_SIZE, &udprelayaddr, NULL); if (pktlen == -1) return; if (enc_ctx_init(&ss->info, &ss->d_ctx, 0)) { redudp_log_error(client, LOG_ERR, "Shadowsocks UDP failed to initialize decryption context."); return; } rc = ss_decrypt(&ss->d_ctx, buff, pktlen, buff2, &fwdlen); enc_ctx_free(&ss->d_ctx); if (!rc) { redudp_log_error(client, LOG_DEBUG, "Can't decrypt packet, dropping it"); return; } header = (ss_header_ipv4 *)buff2; // We do not verify src address, but at least, we need to ensure address type is correct. if (header->addr_type != ss_addrtype_ipv4) { redudp_log_error(client, LOG_DEBUG, "Got address type #%u instead of expected #%u (IPv4).", header->addr_type, ss_addrtype_ipv4); return; } struct sockaddr_in pktaddr = { .sin_family = AF_INET, .sin_addr = { header->addr }, .sin_port = header->port, }; if (fwdlen < sizeof(*header)) { redudp_log_error(client, LOG_DEBUG, "Packet too short."); return; } fwdlen -= sizeof(*header); redudp_fwd_pkt_to_sender(client, buff2 + sizeof(*header), fwdlen, &pktaddr); }
static int be_socket_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data) { switch (op) { case BEV_CTRL_SET_FD: be_socket_setfd(bev, data->fd); return 0; case BEV_CTRL_GET_FD: data->fd = event_get_fd(&bev->ev_read); return 0; case BEV_CTRL_GET_UNDERLYING: default: return -1; } }
static void broadcast_to_peers(struct hub *hub, const char *buf, size_t buflen) { ssize_t n; struct peer *ptr = hub->peers; while (ptr) { n = sendto(event_get_fd(hub->levent), buf, buflen, 0, ptr->addr, ptr->addrlen); if (n > 0) ptr->sent += n; else fprintf(stderr, "Failed sending %i bytes to %s\n", buflen, ptr->name); ptr = ptr->next; } }
void levent_hardware_release(struct lldpd_hardware *hardware) { struct lldpd_events *ev, *ev_next; event_free(hardware->h_timer); hardware->h_timer = NULL; if (!hardware->h_recv) return; log_debug("event", "release events for %s", hardware->h_ifname); for (ev = TAILQ_FIRST(levent_hardware_fds(hardware)); ev; ev = ev_next) { ev_next = TAILQ_NEXT(ev, next); /* We may close several time the same FD. This is harmless. */ close(event_get_fd(ev->ev)); event_free(ev->ev); TAILQ_REMOVE(levent_hardware_fds(hardware), ev, next); free(ev); } free(levent_hardware_fds(hardware)); }
void socket_read_cb(int fd, short events, void *arg) { char msg[4096]; struct event *ev = (struct event*)arg; int len = read(fd, msg, sizeof(msg) - 1); if( len <= 0 ) { printf("some error happen when read\n"); close(event_get_fd(ev)); event_free(ev); return ; } msg[len] = '\0'; printf("recv the client msg: %s", msg); char reply_msg[4096] = "I have recvieced the msg: "; strcat(reply_msg + strlen(reply_msg), msg); write(fd, reply_msg, strlen(reply_msg) ); }
int cleanup_main (struct state *state) { int i; for (i = 0; i < E_MAX; ++i) { struct event *e = state->events[i]; if (e) { int fd = event_get_fd (e); if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL)) close (fd); event_free (e); } } /* The other half was closed above. */ platform->file_close (state->tlsdate_monitor_fd); if (state->tlsdate_pid) { platform->process_signal (state->tlsdate_pid, SIGKILL); platform->process_wait (state->tlsdate_pid, NULL, 0 /* !forever */); } /* Best effort to tear it down if it is still alive. */ close(state->setter_notify_fd); close(state->setter_save_fd); if (state->setter_pid) { platform->process_signal (state->setter_pid, SIGKILL); platform->process_wait (state->setter_pid, NULL, 0 /* !forever */); } /* TODO(wad) Add dbus_cleanup() */ if (state->base) event_base_free (state->base); memset(state, 0, sizeof(*state)); return 0; }
int rs_packet_send (struct rs_packet *pkt, void *user_data) { struct rs_connection *conn = NULL; int err = 0; assert (pkt); assert (pkt->conn); conn = pkt->conn; if (_conn_is_open_p (conn)) packet_do_send (pkt); else if (_conn_open (conn, pkt)) return -1; assert (conn->evb); assert (conn->active_peer); assert (conn->fd >= 0); conn->user_data = user_data; if (conn->bev) /* TCP */ { bufferevent_setcb (conn->bev, NULL, tcp_write_cb, tcp_event_cb, pkt); bufferevent_enable (conn->bev, EV_WRITE); } else /* UDP */ { event_assign (conn->wev, conn->evb, event_get_fd (conn->wev), EV_WRITE, event_get_callback (conn->wev), pkt); err = event_add (conn->wev, NULL); if (err < 0) return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, "event_add: %s", evutil_gai_strerror (err)); } /* Do dispatch, unless the user wants to do it herself. */ if (!conn_user_dispatch_p (conn)) { conn->callbacks.sent_cb = _wcb; conn->user_data = pkt; rs_debug (("%s: entering event loop\n", __func__)); err = event_base_dispatch (conn->evb); if (err < 0) return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, "event_base_dispatch: %s", evutil_gai_strerror (err)); rs_debug (("%s: event loop done\n", __func__)); conn->callbacks.sent_cb = NULL; conn->user_data = NULL; if ((pkt->flags & RS_PACKET_SENT) == 0) { assert (rs_err_conn_peek_code (conn)); return rs_err_conn_peek_code (conn); } } return RSE_OK; }
int32_t epoll_add( void * arg, struct event * ev ) { int32_t fd = 0; int32_t op = 0, events = 0; struct epoll_event epollevent; struct eventpair * eventpair = NULL; struct epoller * poller = (struct epoller *)arg; fd = event_get_fd( (event_t)ev ); if ( fd < 0 ) { return -3; } else if ( fd >= poller->npairs ) { if ( epoll_insert( poller, fd ) != 0 ) { return -1; } } events = 0; op = EPOLL_CTL_ADD; eventpair = &( poller->evpairs[fd] ); if ( eventpair->evread != NULL ) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if ( eventpair->evwrite != NULL ) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if ( ev->events & EV_READ ) { events |= EPOLLIN; } if ( ev->events & EV_WRITE ) { events |= EPOLLOUT; } epollevent.data.u64 = 0; /* avoid valgrind warnning */ epollevent.data.fd = fd; epollevent.events = events; if ( epoll_ctl( poller->epollfd, op, fd, &epollevent ) == -1 ) { return -2; } if ( ev->events & EV_READ ) { eventpair->evread = ev; } if ( ev->events & EV_WRITE ) { eventpair->evwrite = ev; } return 0; }
int32_t epoll_del( void * arg, struct event * ev ) { int32_t fd = 0; int32_t op = 0, events = 0; int32_t delwrite = 1, delread = 1; struct epoll_event epollevent; struct eventpair * eventpair = NULL; struct epoller * poller = (struct epoller *)arg; fd = event_get_fd((event_t)ev); if ( fd >= poller->npairs ) { return -1; } // 简单的删除指定的事件 events = 0; op = EPOLL_CTL_DEL; eventpair = &( poller->evpairs[fd] ); if ( ev->events & EV_READ ) { events |= EPOLLIN; } if ( ev->events & EV_WRITE ) { events |= EPOLLOUT; } // 删除的同时查看该描述符是否支持了其他事件 // 如有, 则不能直接简单的删除 if ( (events & (EPOLLIN|EPOLLOUT)) != (EPOLLIN|EPOLLOUT) ) { if ( (events & EPOLLIN) && eventpair->evwrite != NULL ) { // 删除的是读事件, 写事件仍然要监听 // 并且还需要从写事件中查看是否支持了边缘触发模式 delwrite = 0; events = EPOLLOUT; op = EPOLL_CTL_MOD; } else if ( (events & EPOLLOUT) && eventpair->evread != NULL ) { // 删除的是写事件, 读事件仍然要监听 // 并且还需要从读事件中查看是否支持了边缘触发模式 delread = 0; events = EPOLLIN; op = EPOLL_CTL_MOD; } } epollevent.data.u64 = 0; /* avoid valgrind warnning */ epollevent.data.fd = fd; epollevent.events = events; if ( delread ) { eventpair->evread = NULL; } if ( delwrite ) { eventpair->evwrite = NULL; } return epoll_ctl( poller->epollfd, op, fd, &epollevent ) == -1 ? -2 : 0; }
int tnt_fork(int imsg_fds[2]) { pid_t pid; struct imsgbuf ibuf; struct imsg_data data; struct passwd *pw; struct event_base *evbase = NULL; struct event *sigterm = NULL; struct event *sigint = NULL; struct event *imsg_event = NULL; struct server server; struct event_config *evcfg; switch ((pid = fork())) { case -1: log_err(TNT_OSERR, "fork"); break; case 0: tnt_setproctitle("[unpriv]"); log_set_prefix("unpriv"); break; default: tnt_setproctitle("[priv]"); log_set_prefix("priv"); return pid; } if ((pw = getpwnam(TNETACLE_USER)) == NULL) { log_errx(1, "unknown user " TNETACLE_USER); return TNT_NOUSER; } /*Allocate the event config*/ evcfg = event_config_new(); /* Initialize the OpenSSL library */ SSL_library_init(); SSL_load_error_strings(); /* We MUST have entropy, or else there's no point to crypto. */ if (!RAND_poll()) { log_errx(TNT_SOFTWARE, "[INIT] failed to find an entropy source"); /* never returns */ } if (serv_opts.encryption) server.server_ctx = evssl_init(); else server.server_ctx = NULL; tnt_priv_drop(pw); #if defined(Darwin) /* It's sad isn't it ?*/ event_config_avoid_method(evcfg, "kqueue"); event_config_avoid_method(evcfg, "poll"); event_config_avoid_method(evcfg, "devpoll"); if ((evbase = event_base_new_with_config(evcfg)) == NULL) { log_err(1, "libevent"); } #else if ((evbase = event_base_new_with_config(evcfg)) == NULL) { log_err(1, "libevent"); } #endif sigterm = event_new(evbase, SIGTERM, EV_SIGNAL, &chld_sighdlr, evbase); sigint = event_new(evbase, SIGINT, EV_SIGNAL, &chld_sighdlr, evbase); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGCHLD, SIG_DFL); if (server_init(&server, evbase) == -1) log_errx(1, "failed to init the server socket"); data.ibuf = &ibuf; data.evbase = evbase; data.server = &server; imsg_event = init_pipe_endpoint(imsg_fds, &data); event_add(sigterm, NULL); event_add(sigint, NULL); event_add(imsg_event, NULL); log_info("tnetacle ready"); /* Immediately request the creation of a tun interface */ imsg_compose(&ibuf, IMSG_CREATE_DEV, 0, 0, -1, NULL, 0); log_info("starting event loop"); event_base_dispatch(evbase); /* cleanely exit */ msgbuf_write(&ibuf.w); msgbuf_clear(&ibuf.w); /* Shutdown the server */ server_delete(&server); /* * It may look like we freed this one twice, * once here and once in tnetacled.c but this is not the case. * Please don't erase this ! */ event_free(sigterm); event_free(sigint); close(event_get_fd(imsg_event)); event_free(imsg_event); event_base_free(evbase); event_config_free(evcfg); log_info("tnetacle exiting"); exit(TNT_OK); }