[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.