void echo_close(struct conn *c) { printf("fd %d: closing\n", EVENT_FD(&c->rd_ev)); evbuffer_free(c->buf); event_del(&c->wr_ev); event_del(&c->rd_ev); close(EVENT_FD(&c->rd_ev)); free(c); }
int red_socket_geterrno(struct bufferevent *buffev) { int error; int pseudo_errno; socklen_t optlen = sizeof(pseudo_errno); assert(EVENT_FD(&buffev->ev_read) == EVENT_FD(&buffev->ev_write)); error = getsockopt(EVENT_FD(&buffev->ev_read), SOL_SOCKET, SO_ERROR, &pseudo_errno, &optlen); if (error) { log_errno(LOG_ERR, "getsockopt"); return -1; } return pseudo_errno; }
static void ev_watch_update(AvahiWatch *w, AvahiWatchEvent a_events) { event_del(&w->ev); _ev_watch_add(w, EVENT_FD(&w->ev), a_events); }
static void auto_drop_relay(redsocks_client *client) { if (client->relay) { redsocks_log_error(client, LOG_DEBUG, "dropping relay only"); redsocks_close(EVENT_FD(&client->relay->ev_write)); bufferevent_free(client->relay); client->relay = NULL; } }
int afdt_close_server(void* close_handle) { int ret; struct ev_arg* ev_userdata = close_handle; errno = 0; ret = event_del(&ev_userdata->ev); if (ret < 0) { return ret; } ret = close(EVENT_FD(&ev_userdata->ev)); if (ret < 0) { return ret; } free(close_handle); return 0; }
static void httpr_relay_read_cb(struct bufferevent *buffev, void *_arg) { redsocks_client *client = _arg; httpr_client *httpr = (void*)(client + 1); int dropped = 0; assert(client->state >= httpr_request_sent); redsocks_touch_client(client); httpr_buffer_fini(&httpr->relay_buffer); httpr_buffer_init(&httpr->relay_buffer); if (client->state == httpr_request_sent) { size_t len = EVBUFFER_LENGTH(buffev->input); char *line = redsocks_evbuffer_readline(buffev->input); if (line) { httpr_buffer_append(&httpr->relay_buffer, line, strlen(line)); httpr_buffer_append(&httpr->relay_buffer, "\r\n", 2); unsigned int code; if (sscanf(line, "HTTP/%*u.%*u %u", &code) == 1) { // 1 == one _assigned_ match if (code == 407) { // auth failed http_auth *auth = (void*)(client->instance + 1); if (auth->last_auth_query != NULL && auth->last_auth_count == 1) { redsocks_log_error(client, LOG_NOTICE, "proxy auth failed"); redsocks_drop_client(client); dropped = 1; } else if (client->instance->config.login == NULL || client->instance->config.password == NULL) { redsocks_log_error(client, LOG_NOTICE, "proxy auth required, but no login information provided"); redsocks_drop_client(client); dropped = 1; } else { free(line); char *auth_request = get_auth_request_header(buffev->input); if (!auth_request) { redsocks_log_error(client, LOG_NOTICE, "403 found, but no proxy auth challenge"); redsocks_drop_client(client); dropped = 1; } else { free(auth->last_auth_query); char *ptr = auth_request; ptr += strlen(auth_request_header); while (isspace(*ptr)) ptr++; auth->last_auth_query = calloc(strlen(ptr) + 1, 1); strcpy(auth->last_auth_query, ptr); auth->last_auth_count = 0; free(auth_request); httpr_buffer_fini(&httpr->relay_buffer); if (bufferevent_disable(client->relay, EV_WRITE)) { redsocks_log_errno(client, LOG_ERR, "bufferevent_disable"); return; } /* close relay tunnel */ redsocks_close(EVENT_FD(&client->relay->ev_write)); bufferevent_free(client->relay); /* set to initial state*/ client->state = httpr_recv_request_headers; /* and reconnect */ redsocks_connect_relay(client); return; } } } else if (100 <= code && code <= 999) { client->state = httpr_reply_came; } else { redsocks_log_error(client, LOG_NOTICE, "%s", line); redsocks_drop_client(client); dropped = 1; } } free(line); } else if (len >= HTTP_HEAD_WM_HIGH) { redsocks_drop_client(client); dropped = 1; } } if (dropped) return; while (client->state == httpr_reply_came) { char *line = redsocks_evbuffer_readline(buffev->input); if (line) { httpr_buffer_append(&httpr->relay_buffer, line, strlen(line)); httpr_buffer_append(&httpr->relay_buffer, "\r\n", 2); if (strlen(line) == 0) { client->state = httpr_headers_skipped; } free(line); } else { break; } } if (client->state == httpr_headers_skipped) { if (bufferevent_write(client->client, httpr->relay_buffer.buff, httpr->relay_buffer.len) != 0) { redsocks_log_error(client, LOG_NOTICE, "bufferevent_write"); redsocks_drop_client(client); return; } redsocks_start_relay(client); } }
bool MessagePumpLibevent::WatchFileDescriptor(int fd, bool persistent, int mode, FileDescriptorWatcher *controller, Watcher *delegate) { assert(fd > 0); assert(controller); assert(delegate); assert(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE); int event_mask = persistent ? EV_PERSIST : 0; if (mode & WATCH_READ) { event_mask |= EV_READ; } if (mode & WATCH_WRITE) { event_mask |= EV_WRITE; } std::unique_ptr<event> evt(controller->ReleaseEvent()); if (evt.get() == NULL) { // Ownership is transferred to the controller. evt.reset(new event); } else { // Make sure we don't pick up any funky internal libevent masks. int old_interest_mask = evt.get()->ev_events & (EV_READ | EV_WRITE | EV_PERSIST); // Combine old/new event masks. event_mask |= old_interest_mask; // Must disarm the event before we can reuse it. event_del(evt.get()); // It's illegal to use this function to listen on 2 separate fds with the // same |controller|. if (EVENT_FD(evt.get()) != fd) { std::cerr << "FDs don't match" << EVENT_FD(evt.get()) << "!=" << fd; return false; } } // Set current interest mask and message pump for this event. event_set(evt.get(), fd, event_mask, OnLibeventNotification, controller); // Tell libevent which message pump this socket will belong to when we add it. if (event_base_set(event_base_, evt.get())) { return false; } // Add this socket to the list of monitored sockets. if (event_add(evt.get(), NULL)) { return false; } // Transfer ownership of evt to controller. controller->Init(evt.release()); controller->set_watcher(delegate); controller->set_pump(this); return true; }