[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [Libevent-users] Libevent, DBus, Netlink, peeking at packet lengths, etc.
On 16 August 2016 at 20:42, Philip Prindeville
<philipp_subx@xxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi,
>
> I'm fairly new to using libevent, having done most of my event driven
> programming in C++ with either Boost or Perl, but needed to add multiple
> pending transaction support to a Tacacs+ proxy written in C so I decided to
> have a look at libevent.
>
> So far, it all seems pretty straightforward and I'm getting the hang of it.
>
> I did have a question about supporting other socket types besides the usual
> TCP or UDP transports.
>
> Is there a preferred way of supporting Netlink or DBus traffic? I ask
> because I'm thinking of a long-running daemon on a laptop that might need to
> get notifications about roaming onto different network types via Netlink,
> for instance. I did see this library out there but wasn't sure how complete
> and tested it was:
>
> https://github.com/dex/dbus-service
>
> Also, in the case of handling a protocol with fixed-size records (like
> Tacacs+) running over TCP, is there a preferred way to read a
> packet-at-a-time? Since it's TCP, you have no record boundaries (unlike UDP
> or TP-4), so you have to find the packet length inside the header.
>
> In my case, in my read callback, I'm doing this as:
>
> evbuf = bufferevent_get_input(bev);
>
> n = evbuffer_get_length(evbuf);
>
I've tended to use evbuffer_get_contiguous_space(), since that's the
largest amount of space you can read without buffer copying. Of
course, a TCP write() from your peer needn't end up as one read() at
your end, and hence might not yield contiguous space - so an
evbuffer_get_length() is a useful fallback if the contiguous space is
non-zero but too small for your header.
> /* evbuffer_pullup() returns NULL if there aren't enough bytes in
> * the buffer yet to pull-up as many as are requested.
> */
> start = evbuffer_pullup(evbuf, TAC_PLUS_HDR_SIZE);
> if (! start)
> return;
>
> th = (HDR *)start;
>
> /* should probably bcopy th->datalength to a word-aligned buffer
> * first, in case we're on a platform which doesn't handle word
> * fetches on unaligned addresses
> */
>
> length = ntohl(th->datalength) + TAC_PLUS_HDR_SIZE;
>
> /* if we're short, we'll get called again when more data arrives
> */
> if (n < length)
> return;
>
> u_char *pkt = malloc(length);
>
> /* copy out... */
> i = evbuffer_remove(evbuf, pkt, length);
>
> tac_parse_pkt(ctx->sess, ctx, pkt, length);
>
> free(pkt);
> }
>
> But wondered if there's a better or prototypical way of handling this?
>
> Is it worth setting the socket low-water market to "length" so that we only
> get dispatched one more time if data trickles in?
>
> Also, is there any interest in adding 'profiling' support to the event
> handlers to see how long they run (in real-time, probably using
> gettimeofday()) and generating warnings in debug- (or development-) mode if
> they exceed an upper threshold (say 10ms execution time)?
>
> Thanks,
>
> -Philip
>
> ***********************************************************************
> To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
> unsubscribe libevent-users in the body.
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users in the body.