Libevent HTTP Server & compression? - http

I'm using libevent2 in my application to host a http server. I cant find a built-in way to compress the output.
These are the options I'm considering:
Apply gzip/deflate compression using zlib in my app before sending out the response
Hack libevent's http.c to expose evhttp_connection->bufev (the bufferevent object), and apply a zlib filter for outgoing data
(Both read the supported compression formats from the Accept-Encoding header)
Is there some easier way I'm overlooking, or is this pretty much it?

I use this little trick to obtain the file descriptor of an evhttp_connection, which is right next to the pointer you want. It's a nasty hack, but it's simple, and easier that having to rebuild libevent. It has been tested under x86_64 and runs fine.
static void
send_document_cb(struct evhttp_request *req, void *arg)
{
// ....
struct evhttp_connection *this_connection;
this_connection = evhttp_request_get_connection(req);
int *tricky;
tricky = (((int *)this_connection) + 4);
int fd = *tricky;
printf("fd: %i\n", fd);
// ....
}
Looking at the structure definition (beneath), it appears the bufev you want should be accessible using (((void *)this_connection) + 8) or something very similar.
struct evhttp_connection {
TAILQ_ENTRY(evhttp_connection) next;
evutil_socket_t fd;
struct bufferevent *bufev;
...
}

Non-hacky way to get the FD socket in 2022:
static void _genericCallback( evhttp_request *req, void *arg )
{
evhttp_connection *conn = evhttp_request_get_connection( req );
if( conn )
{
bufferevent *buffevt = evhttp_connection_get_bufferevent( conn );
if( buffevt )
{
evutil_socket_t fd = bufferevent_getfd( buffevt );
if( fd >= 0 )
{
// Use the socket
setsockopt( fd, ... );
}
}
}
}
evhttp_set_gencb( server, _genericCallback, 0 );

Related

How to implement a TCP server that receives and sends data in two processes?

I am trying to implement a TCP server using C in Linux. I want this server to accept incoming data forever from multiple clients and at the same time send some data back to each connected client in every 3 seconds.
My problem is I don't know how to properly do send() in a different process than the one handling the client.
What I am doing is at the beginning of the program do a fork() and do
while (1) {
sleep(3);
// compute and `send()` data to each connected peers
}
in child process, do
sock = create_socket();
while (1) {
client_sock = accept_connection(sock);
if (fork() == 0) {
close(sock);
handle_client(client_sock);
exit(0);
}
close(client_sock);
// clean up zombies
}
in parent process. handle_client() is simply recv() data in a infinite loop. Because send() and recv() are executed in different processes, I couldn't use the socket file descriptors to send() in parent process. What do I need to do in the parent process to do the send()?
You have three levels of processes, a parent, a child, and many grandchildren. Get rid of these levels, and do not fork at all; instead using an event-driven model in a single process.
In rough pseudo-code (translate to your preferred language):
listening_fd = create_socket();
EventQueueOfSomeKind q; // kqueue()-style
q.add_or_update_event(listening_fd, EVFILT_READ, EV_ENABLE);
q.add_or_update_event(3, EVFILT_TIMER, EV_ENABLE, NOTE_SECONDS);
FDToContextMapOfSomeKind context_map;
EventVector event_vector; // vector of kevent-like things
while (1) {
q.wait_for_events(&event_vector); // kevent()-style
foreach e <- event_vector {
switch (e.type) {
case EVFILT_READ:
if (listening_fd == e.fd) {
client_sock = accept_connection(e.fd, SOCK_NONBLOCK);
q.add_or_update_event(client_sock, EVFILT_READ, EV_ENABLE);
q.add_or_update_event(client_sock, EVFILT_WRITE, EV_DISABLE);
context_map.add_new_context(client_socket);
} else {
// Must be one of the client sockets
if (e.flags & EV_EOF) {
context_map.remove_context(e.fd);
q.remove_event(e.fd, EVFILT_READ);
q.remove_event(e.fd, EVFILT_WRITE);
close(e.fd);
} else {
recv(e.fd, buffer);
handle_client_input(&context_map[e.fd], buffer);
}
}
break;
case EVFILT_WRITE:
if (has_queued_output(context_map[e.fd])) {
send(e.fd, pull_queued_output(&context_map[e.fd]));
} else {
q.add_or_update_event(client_sock, EVFILT_WRITE, EV_DISABLE);
}
break;
case EVFILT_TIMER:
foreach client_sock,context <- context_map {
push_queued_output(&context, computed_data(context));
q.add_or_update_event(client_sock, EVFILT_WRITE, EV_ENABLE);
}
break;
}
}
}
I have glossed over partial send()s and recv()s, write-side shutdown, and all error handling but this is the general idea.
Further reading
https://github.com/mheily/libkqueue
Jonathan Lemon. kqueue. OpenBSD System Calls Manual.
Jonathan Lemon. kqueue. Darwin BSD Calls Manual. Apple corporation.
This is a solution using Linux epoll and timerfd (error handling is omitted):
int start_timer(unsigned int interval) {
int tfd;
struct itimerspec tspec;
tspec.it_value.tv_sec = 1;
tspec.it_value.tv_nsec = 0;
tspec.it_interval.tv_sec = 3;
tspec.it_interval.tv_nsec = 0;
tfd = timerfd_create(CLOCK_MONOTONIC, 0);
timerfd_settime(tfd, TFD_TIMER_ABSTIME, &tspec, NULL);
return tfd;
}
void epset_add(int epfd, int fd, uint32_t events)
{
struct epoll_event ev;
ev.data.fd = fd;
ev.events = events;
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
}
int main()
{
int epfd, tfd, sock, nfds, i;
struct epoll_event events[MAX_EVENTS];
/* create new epoll instance */
epfd = epoll_create1(0);
tfd = start_timer(TIMER_INTERVAL);
/* socket(), bind() and listen() omitted in create_socket() */
sock = create_socket(PORT_NUMBER);
/* add sock and tfd to epoll set */
epset_add(epfd, tfd, EPOLLIN);
epset_add(epfd, sock, EPOLLIN | EPOLLET);
for (;;) {
for (i = 0; i < nfds; ++i) {
if (events[i].data.fd == tfd) {
/* handle timer notification, it's run
periodically with interval TIMER_INTERVAL */
} else if (events[i].data.fd == sock) {
/* accept() incoming connections,
set non-blocking,
and add new connection sockets to epoll set */
} else {
/* recv() from connection sockets and handle */
}
}
}
}
This program was helpful https://github.com/eklitzke/epollet/blob/master/poll.c and I added timerfd to the epoll set so the server keeps listening and receiving data and at the same time can send data to the clients periodically.

decrypt function at run time and use it QT c++

I'm new to QT and I'm trying to create an encrypted function.
Overall what you do in C / C ++ is:
Take pointer to function
make the function page rwx
Encrypt it (for the example I encrypt and decrypt in the same program)
Decrypt it and run it
A simple code in C will happen roughly like this:
void TestFunction()
{
printf("\nmsgbox test encrypted func\n");
}
// use this as a end label
void FunctionStub() { return; }
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
char * addr = (char *)dwStartAddress;
for (int i = 0; i< dwSize; i++)
{
addr[i] ^= 0xff;
}
}
DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
DWORD dwFunctionSize = 0, dwOldProtect;
DWORD *fnA = NULL, *fnB = NULL;
fnA = (DWORD *)Function;
fnB = (DWORD *)StubFunction;
dwFunctionSize = (fnB - fnA);
VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // make function page read write execute permission
return dwFunctionSize;
}
int main()
{
DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
printf("use func");
TestFunction();
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function
printf("after enc");
//TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function
printf("after\n");
TestFunction(); // Fine here
getchar();
}
When I try to run such an example in QT I get a run time error.
Here is the code in QT:
void TestFunction()
{
QMessageBox::information(0, "Test", "msgbox test encrypted func");
}
void FunctionStub() { return; }
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
char * addr = (char *)dwStartAddress;
for (int i = 0; i< dwSize; i++)
{
addr[i] ^= 0xff; // here i get seg. fault
}
}
DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
DWORD dwFunctionSize = 0, dwOldProtect;
DWORD *fnA = NULL, *fnB = NULL;
fnA = (DWORD *)Function;
fnB = (DWORD *)StubFunction;
dwFunctionSize = (fnB - fnA);
VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // Need to modify our privileges to the memory
QMessageBox::information(0, "Test", "change func to read write execute ");
return dwFunctionSize;
}
void check_enc_function()
{
DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
QMessageBox::information(0, "Test", "use func");
TestFunction();
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function -> ### i get seg fault in here ###
QMessageBox::information(0, "Test", "after enc");
TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.
XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function
QMessageBox::information(0, "Test", "after dec");
TestFunction(); // Fine here
getchar();
}
Why should this happen?
QT is supposed to behave like precision as standard C ++ ...
post Scriptum.
Interestingly in the same matter, what is the most legitimate way to keep an important function encrypted (the reason it is encrypted is DRM)?
Legitimately I mean that anti-viruses will not mistakenly mark me as a virus because I defend myself.
PS2
If I pass an encrypted function over the network (say, I will build a server client schema that the client asks for the function it needs to run from the server and the server sends it to it if it is approved) How can I arrange the symbols so that the function does not collapse?
PS3
How in QT can I turn off the DEP and ASLR defenses? (In my opinion so that I can execute PS 2. I have to cancel them)
Thanks
yoko
The example is undefined behaviour on my system.
The first and main issue in your code is:
void TestFunction() { /* ... */ }
void FunctionStub() { return; }
You assume that the compiler will put FunctionStub after TestFunction without any padding. I compiled your example and FunctionStub in my case was above TestFunction which resulted in a negative dwFunctionSize.
dwFunctionSize = (fnB - fnA);
TestFunction located at # 0xa11d90
FunctionStub located at # 0xa11b50
dwFunctionSize = -0x240
Also in XorBlock
addr[i] ^= 0xff;
Is doing nothing.
I assume you want to write in XorBlock to the memory location to XOR the entire TestFunction.
You could do something like this:
void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
DWORD dwEndAddress = dwStartAddress + dwSize;
for(DWORD i = dwStartAddress; i < dwEndAddress; i++) {
// ...
}
}
I can't see any Qt-specific in your example. Even if it's Qt function call it's just a call. So I guess you have undefined behaviour in both examples but only second one crashes.
I can't see any reason for compiler and linker to keep function order. For example GCC let you specify the code section for each function. So you can reorder it in executable without reordering in cpp.
I think you need some compiler specific things to make it work.

LwIP Netconn API + FreeRTOS TCP Client Buffer Issue

I've been trying to modify the tcp server example with LwIP in STM32F4DISCOVERY board. I have to write a sender which does not necessarily have to reply server responses. It can send data with 100 ms frequency, for example.
Firstly, the example of TCP server is like this:
static void tcpecho_thread(void *arg)
{
struct netconn *conn, *newconn;
err_t err;
LWIP_UNUSED_ARG(arg);
/* Create a new connection identifier. */
conn = netconn_new(NETCONN_TCP);
if (conn!=NULL) {
/* Bind connection to well known port number 7. */
err = netconn_bind(conn, NULL, DEST_PORT);
if (err == ERR_OK) {
/* Tell connection to go into listening mode. */
netconn_listen(conn);
while (1) {
/* Grab new connection. */
newconn = netconn_accept(conn);
/* Process the new connection. */
if (newconn) {
struct netbuf *buf;
void *data;
u16_t len;
while ((buf = netconn_recv(newconn)) != NULL) {
do {
netbuf_data(buf, &data, &len);
//Incoming package
.....
//Check for data
if (DATA IS CORRECT)
{
//Reply
data = "OK";
len = 2;
netconn_write(newconn, data, len, NETCONN_COPY);
}
} while (netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
/* Close connection and discard connection identifier. */
netconn_close(newconn);
netconn_delete(newconn);
}
}
} else {
printf(" can not bind TCP netconn");
}
} else {
printf("can not create TCP netconn");
}
}
I modified this code to obtain a client version, this is what I've got so far:
static void tcpecho_thread(void *arg)
{
struct netconn *xNetConn = NULL;
struct ip_addr local_ip;
struct ip_addr remote_ip;
int rc1, rc2;
struct netbuf *Gonderilen_Buf = NULL;
struct netbuf *gonderilen_buf = NULL;
void *b_data;
u16_t b_len;
IP4_ADDR( &local_ip, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3 );
IP4_ADDR( &remote_ip, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );
xNetConn = netconn_new ( NETCONN_TCP );
rc1 = netconn_bind ( xNetConn, &local_ip, DEST_PORT );
rc2 = netconn_connect ( xNetConn, &remote_ip, DEST_PORT );
b_data = "+24C"; // Data to be send
b_len = sizeof ( b_data );
while(1)
{
if ( rc1 == ERR_OK )
{
// If button pressed, send data "+24C" to server
if (GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) == Bit_SET)
{
Buf = netbuf_new();
netbuf_alloc(Buf, 4); // 4 bytes of buffer
Buf->p->payload = "+24C";
Buf->p->len = 4;
netconn_write(xNetConn, Buf->p->payload, b_len, NETCONN_COPY);
vTaskDelay(100); // To see the result easily in Comm Operator
netbuf_delete(Buf);
}
}
if ( rc1 != ERR_OK || rc2 != ERR_OK )
{
netconn_delete ( xNetConn );
}
}
}
While the writing operation works, netconn_write sends what's on its buffer. It doesnt care whether b_data is NULL or not. I've tested it by adding the line b_data = NULL;
So the resulting output in Comm Operator is like this:
Rec:(02:47:27)+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C+24C
However, I want it to work like this:
Rec:(02:47:22)+24C
Rec:(02:47:27)+24C
Rec:(02:57:12)+24C
Rec:(02:58:41)+24C
The desired write operation happens when I wait for around 8 seconds before I push the button again.
Since netconn_write function does not allow writing to a buffer, I'm not able to clear it. And netconn_send is only allowed for UDP connections.
I need some guidance to understand the problem and to generate a solution for it.
Any help will be greately appreciated.
It's just a matter of printing the result in the correct way.
You can try to add this part of code before writing in the netbuf data structure:
char buffer[20];
sprintf(buffer,"24+ \n");
Buf->p->payload = "+24C";
I see one or two problems in your code, depending on what you want it exactly to do. First of all, you're not sending b_data at all, but a constant string:
b_data = "+24C"; // Data to be send
and then
Buf->p->payload = "+24C";
Buf->p->len = 4;
netconn_write(xNetConn, Buf->p->payload, b_len, NETCONN_COPY);
b_data is not anywhere mentioned there. What is sent is the payload. Try Buf->p->payload = b_data; if it's what you want to achieve.
Second, if you want the +24C text to be sent only once when you push the button, you'll have to have a loop to wait for the button to open again before continuing the loop, or it will send +24C continuously until you stop pushing the button. Something in this direction:
while (GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) == Bit_SET) {
vTaskDelay(1);
}

Call by reference with QVector

I have in an Object an QVector of Coordinates (my type) that I want to transfer to an other Vector ( I validate and than want to use ist ).
Header
bool getVector(QVector<Coordinates> &getCoordinates );
C File
static QVector<Coordinates> current;
int getVector( QVector<Coordinates> &getCoordinates)
{
.... stuff ...
getCoordinates = current;
.... stuff ....
return 0;
}
And I use it like
....
QVector<Coordinates> currentCoordinates;
getVector(currentCoordinates);
currentCoordinates.X // CRASH
The debugger goes to this line where an Live Crash happens
inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
So my how can I fix this? As I can use this to get all the other Variables with this methode.
A likely cause of your problem is that current has not been constructed before getVector is called. Initialization of static objects in C++ is a thorny area, and a frequent source of bugs - for more information, see this question, and the static initialization order fiasco FAQ entry.
A simple solution to this problem is to provide access to current via a function, i.e. replace
static QVector<Coordinates> current;
with
static QVector<Coordinates>& getCurrent()
{
static QVector<Coordinates> current;
return current;
}
Note, however, that the function as written above is not thread-safe. If multiple threads may call getCurrent, then it should be protected with a QMutex.
For gareth and the Forum :
the header:
typedef QVector<Coordinates> VesselCoordinates;
bool (*getVessel)(Charakter forCharakter, Vessel& getVessel,VesselCoordinates &getCoordinates );
later i bind tis function pointer to an static function ( cause this part of my Program will be one day convertet to c)
cpp file lower layer:
static struct {
Charakter currentPlayerVessel;
VesselCoordinates possibility;
}data;
static bool getVessel(Charakter forCharakter, Vessel& getVessel,VesselCoordinates &getCoordinates );
// funktion to bind the funktion pointer to this static funktion so it can be called outside the File
static bool serverNamespace::getVessel(Charakter forCharakter, Vessel& getVessel,VesselCoordinates &getCoordinates )
{
bool retValue= false;
if ( forCharakter == data.currentPlayerVessel){
// TODO abfragen ob die Adresse regestriert ist!
if ((true == minSize()) and ((true == shipsInRow())or (true == shipsInLine())))
{
retValue = true;
Vessel test = (Vessel)data.possibility.size();
getVessel = test;
getCoordinates = data.possibility;
}
}
return retValue;
}
And then i can use this in the upper layer cpp file to get the information i need:
// in an Funktion :
VesselCoordinates currentCoordinates;
currentCoordinates.clear();
Vessel currentVessel;
if (true == basicFleet->getVessel(currentCharakter,currentVessel, currentCoordinates ))
// doing stuff to it
so its worik fine but your idea worked just as fine. Maybe you can see why my idea is also working.
Thank you
elektor

segfault after return 0;

I wrote a program to test my binary tree and when I run it, the program seems to crash (btree.exe has stopped working, Windows is checking for a solution ...).
When I ran it through my debugger and placed the breakpoint on the function I suspect is causing it, destroy_tree(), it seemed to run as expected and returned back to the main function. Main, in turn, returned from the program but then the cursor jumped back to destroy_tree() and looped recusively within itself.
The minimal code sample is below so it can be ran instantly. My compiler is MinGW and my debugger is gdb (I'm using Code::Blocks).
#include <iostream>
using namespace std;
struct node
{
int key_value;
node *left;
node *right;
};
class Btree
{
public:
Btree();
~Btree();
void insert(int key);
void destroy_tree();
private:
node *root;
void destroy_tree(node *leaf);
void insert(int key, node *leaf);
};
Btree::Btree()
{
root = NULL;
}
Btree::~Btree()
{
destroy_tree();
}
void Btree::destroy_tree()
{
destroy_tree(root);
cout<<"tree destroyed\n"<<endl;
}
void Btree::destroy_tree(node *leaf)
{
if(leaf!=NULL)
{
destroy_tree(leaf->left);
destroy_tree(leaf->right);
delete leaf;
}
}
void Btree::insert(int key, node *leaf)
{
if(key < leaf->key_value)
{
if(leaf->left!=NULL)
insert(key, leaf->left);
else
{
leaf->left = new node;
leaf->left->key_value = key;
leaf->left->left = NULL;
leaf->left->right = NULL;
}
}
else if (key >= leaf->key_value)
{
if(leaf->right!=NULL)
insert(key, leaf->right);
else
{
leaf->right = new node;
leaf->right->key_value = key;
leaf->right->left = NULL;
leaf->right->right = NULL;
}
}
}
void Btree::insert(int key)
{
if(root!=NULL)
{
insert(key, root);
}
else
{
root = new node;
root->key_value = key;
root->left = NULL;
root->right = NULL;
}
}
int main()
{
Btree tree;
int i;
tree.insert(1);
tree.destroy_tree();
return 0;
}
As an aside, I'm planning to switch from Code::Blocks built-in debugger to DDD for debugging these problems. I heard DDD can display visually pointers to objects instead of just displaying the pointer's address. Do you think making the switch will help with solving these types of problems (data structure and algorithm problems)?
Your destroy_tree() is called twice, you call it once and then it gets called after the execution leaves main() from the destructor.
You may think it should work anyway, because you check whether leaf!=NULL, but delete does not set the pointer to NULL. So your root is not NULL when destroy_tree() is called for the second time,
Not directly related (or maybe it is) to your problem, but it's good practice to give structs a constructor. For example:
struct node
{
int key_value;
node *left;
node *right;
node( int val ) : key_val( val ), left(NULL), right(NULL) {}
};
If you do this, your code becomes simpler, because you don't need worry about setting the pointers when you create a node, and it is not possible to forget to initialise them.
Regarding DDD, it;'s a fine debugger, but frankly the secret of debugging is to write correct code in the first place, so you don't have to do it. C++ gives you a lot of help in this direction (like the use of constructors), but you have to understand and use the facilities it provides.
Btree::destroy_tree doesn't set 'root' to 0 after successfully nuking the tree. As a result, the destructor class destroy_tree() again and you're trying to destroy already destroyed objects.
That'll be undefined behaviour then :).
Once you destroy the root.
Make sure it is NULL so it does not try to do it again (from the destructor)
void Btree::destroy_tree(node *leaf)
{
if(leaf!=NULL)
{
destroy_tree(leaf->left);
destroy_tree(leaf->right);
delete leaf;
leaf = NULL; // add this line
}
}

Resources