[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [Libevent-users] help with server
On Sun, Oct 09, 2016 at 01:51:36PM -0400, Littlefield, Tyler wrote:
> All,
> I sent this a while ago. I'm currently working on a passthrough proxy
Hi,
Can you post here a link (for "a while ago" thing)?
> for a larger project. I've pasted the code here, but for whatever reason
> when I connect my data does not get sent through to the other side. I
> have debugged it to know that:
> 1) the requests are parsed correctly.
> 2) The connection is made.
> 3) The data is moved from one buffer to the next at the end of OnRead.
> Does anyone have any thoughts? I'm struggling to figure out why the data
> wouldn't be sent. Any tips would be greatly appreciated. I've dropped
> the relevant code here.
You can take a look at [1] for example.
[1]: https://github.com/libevent/libevent/blob/b9c5077e99b8be6ec1fab2fb8177439ef9cb76e1/sample/le-proxy.c#L51
> struct State
> {
> bufferevent* origenation;
> bufferevent* connection;
> Listener* listener;
> RequestState state;
> };
>
> void Listener::Listen(event_base* base)
> {
> _base = base;
I guess this is global.
> _listener = evconnlistener_new_bind(base, AcceptConnectionCallback,
> (void*)this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct
> sockaddr *)&_addr, sizeof(_addr));
> if (!_listener)
> {
> int err = EVUTIL_SOCKET_ERROR();
> throw std::runtime_error("Could not create listener, got
> error: "+std::string(evutil_socket_error_to_string(err))+".");
> }
>
> evconnlistener_set_error_cb(_listener, AcceptErrorCallback);
So somewhere you called event_base_dispatch()
> }
>
> void Listener::OnRead(bufferevent *bufferevt, State* state)
> {
> evbuffer *src = nullptr;
> evbuffer* dst = nullptr;
> size_t len = 0;
>
> if (state->origenation == bufferevt)
> {
> src = bufferevent_get_input(bufferevt);
> if (state->connection)
> dst = bufferevent_get_output(state->connection);
> }
> else
> {
> src = bufferevent_get_input(state->connection);
> dst = bufferevent_get_output(state->origenation);
> }
So you have a bidirectional connections, are you sure that this part
actually works?
>
> len = evbuffer_get_length(src);
> if (bufferevt == state->origenation)
> {
> if (state->state == RequestState::Half)
> {
> if (result)
> {
> std::string response =
> "<html>\n<head>\n<title>Error!</title>\n</head>\n<body>\n";
> response += "<h1>An error has
> occured.</h1>\n<p>\n";
> response +=
> std::string(gai_strerror(result)) + "</p>\n</body>\n</html>\n";
> dst = bufferevent_get_output(bufferevt);
> evbuffer_copyout(dst,
> (void*)response.c_str(), response.length());
Does this works?
> evbuffer_drain(src, len);
> return;
> }
>
>
> state->connection = bufferevent_socket_new(_base,
> -1, BEV_OPT_CLOSE_ON_FREE);
Please send code without wrapping, and use attachments for this.
> result =
> bufferevent_socket_connect(state->connection, servinfo->ai_addr,
> servinfo->ai_addrlen);
You can just use buffervent_socket_connect_hostname() instead of doing
this manually.
> dst = bufferevent_get_output(state->connection);
So what you have now is just a socket that doesn't meant to be
connected, since it is NONBLOCK you can take a look at [2] to see how
you can handle it, and of course it will not work for you, until you
will connect to it.
[2]: https://github.com/libevent/libevent/blob/b9c5077e99b8be6ec1fab2fb8177439ef9cb76e1/http.c#L1553
> bufferevent_setcb(state->connection, ReadCallback,
> NULL, EventCallback, (void*)state);
> bufferevent_enable(state->connection, EV_READ|EV_WRITE);
> }
> }
>
> evbuffer_add_buffer(dst, src);
> }
And it will be far more better if you will provide working 50L sample.
Azat
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users in the body.