Skip to content

Instantly share code, notes, and snippets.

@paulfariello
Created July 31, 2017 12:35
Show Gist options
  • Save paulfariello/0403f5be9b6b07303cccc9aa3362b9fc to your computer and use it in GitHub Desktop.
Save paulfariello/0403f5be9b6b07303cccc9aa3362b9fc to your computer and use it in GitHub Desktop.
libevent offset ignored in evbuffer_add_file()
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>
static void
event_write(struct bufferevent *bev, void *_)
{
struct evbuffer *outbuf = bufferevent_get_output(bev);
int fd;
fd = open("random.data", O_RDONLY);
evbuffer_clear_flags(outbuf, EVBUFFER_FLAG_DRAINS_TO_FD);
evbuffer_add_file(outbuf, fd, 0x200, 0x100);
bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
}
static void
event_accept(struct evconnlistener *evlistener, evutil_socket_t sockfd,
struct sockaddr *addr, int addrlen, void *_)
{
struct event_base *evb = evconnlistener_get_base(evlistener);
struct bufferevent *bev;
evutil_make_socket_nonblocking(sockfd);
bev = bufferevent_socket_new(evb, sockfd,
BEV_OPT_DEFER_CALLBACKS
| BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, NULL, event_write, NULL, NULL);
bufferevent_enable(bev, EV_READ|EV_WRITE);
}
int
main(int argc, char **argv)
{
struct event_base *evb;
struct sockaddr_in localhost;
struct evconnlistener *evlistener;
int client;
int nodelay = 1;
unsigned char buf[256];
localhost.sin_family = AF_INET;
localhost.sin_port = htons(6881);
localhost.sin_addr.s_addr = inet_addr("127.0.0.1");
evb = event_base_new();
evlistener = evconnlistener_new_bind(evb, event_accept, NULL,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
SOMAXCONN,
(struct sockaddr *)&localhost,
sizeof(struct sockaddr_in));
client = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
setsockopt(client, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
connect(client, (struct sockaddr *)&localhost, sizeof(struct sockaddr_in));
event_base_loop(evb, EVLOOP_ONCE|EVLOOP_NONBLOCK); /* For accept */
event_base_loop(evb, EVLOOP_ONCE|EVLOOP_NONBLOCK); /* For write */
event_base_loop(evb, EVLOOP_ONCE|EVLOOP_NONBLOCK); /* For write ? */
ssize_t len;
while ((len = read(client, buf, 256)) > 0) {
event_base_loop(evb, EVLOOP_ONCE|EVLOOP_NONBLOCK);
write(STDOUT_FILENO, buf, len);
}
return EXIT_SUCCESS;
}
@paulfariello
Copy link
Author

paulfariello commented Jul 31, 2017

dd if=/dev/urandom of=random.data bs=1M count=1
gcc -g -o eventtest -levent event.c && ./eventtest | xxd
dd if=random.data bs=256 skip=2 count=1 | xxd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment