예제 #1
0
파일: echod.c 프로젝트: trcm/COMP3301
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);
}
예제 #2
0
파일: utils.c 프로젝트: antenore/redsocks
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;
}
예제 #3
0
static void
ev_watch_update(AvahiWatch *w, AvahiWatchEvent a_events)
{
  event_del(&w->ev);

  _ev_watch_add(w, EVENT_FD(&w->ev), a_events);
}
예제 #4
0
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;
	}
}
예제 #5
0
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;
}
예제 #6
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;
}