C/C++ Forking and Using Pipes to Exchange Data Between Parent and Child

Aim
Pipes are form of inter-process communication. They are very useful to synchronize access to resources, notification and exchanging data. In this example we will use fork to spawn a process and then communicate between the child process and parent process using pipes.

Assumptions
You have a C++ compiler (g++ in this example) and access to a linux environment or cygwin.

Application
In this simple example we use pipe to create the pipes. We then fork and use write and read on the pipes to exchange information. Also note that we call waitpid in the parent to stop it exiting before the child has quit.

Let us have a look at the code below. This file will be saved as forking_pipes.cpp
 1. #include <stdlib.h>
 2. #include <stdio.h>
 3. #include <string.h>
 4. #include <unistd.h>
 5. #include <errno.h>
 6. #include <sys/types.h>
 7. #include <sys/wait.h>
 8. 
 9. 
10. int main(int argv, char** argc){
11. 
12.     int pipes[2];
13.     char readbuf[64]={0};
14.     char writebuf[64]={0};
15.     int childpid;
16. 
17.     if(pipe(pipes)<0){
18.         perror("Pipe allocation failed");
19.         exit(0);
20.     }
21. 
22.     switch(childpid=fork()){
23.         case -1:
24.             perror("Problem with fork\n");
25.             break;
26. 
27.         case 0:  //Child
28.             //Writing
29.             sprintf(writebuf, "Hello from %d", getpid());
30.             if(write(pipes[1], writebuf, strlen(writebuf))<0){
31.                 perror("Child write failed\n");
32.             }
33. 
34.             //Reading
35.             if(read(pipes[0], readbuf, 64)>0){
36.                 printf("Child read - %s\n", readbuf);
37.             }
38.             else{
39.                 perror("child read failed\n");
40.             }
41. 
42.             break;
43.         
44.         default: //Parent
45.             //Reading
46.             if(read(pipes[0], readbuf, 64)>0){
47.                 printf("Parent read - %s\n", readbuf);
48.             }
49.             else{
50.                 perror("Parent read failed\n");
51.             }
52.             
53.             //Writing
54.             sprintf(writebuf, "Hello from parent");
55.             if(write(pipes[1], writebuf, strlen(writebuf))<0){
56.                 perror("Parent write failed\n");
57.             }
58. 
59.             waitpid(childpid,0,0);
60. 
61.             break;
62.     }
63. }
Hide line numbers

Compile the code

..workspace\Forkingpipes>g++ forking_pipes.cpp

pipes[0] is the reading pipe and pipe[1] is the writing pipe. In the parent whatever you write to pipe[1] can be read at the child using pipe[0]. In the child whatever you write to pipe[1] can be read at the Parent using pipe[0].

If you wish to spawn multiple children then you have to have multiple pipe pairs. This means you will have to use select in the parent to find out which pipes are ready for writing and reading.

Bandwidth Throttling and Connection Limiting for Web, Proxy and Email Servers


Aim
The aim of this program is to create a self regulating tcp/ip connection forwarding program that can limit connections and do per IP bandwidth throttling and connection limiting. This can be used to give bandwidth throttling and connection limiting to proxy, email, web and ftp servers. It will work with any server such as tomcat, apache, glassfish, squid, weblogic etc as it runs as a separate standalone application. This software is now called SpeedBump. This can be easily used to throttle Apache and Squid very easily.

Resources

The key features are
  1. Set the maximum number of con-current connections. Similar to apache's MaxClients.
  2. Set maximum con-current connections per ip. Similar to conn-limit in iptables.
  3. Set the new connection burst and average connections per second per ip. Similar to limit-burst in iptables.
  4. Set the uplink and downlink throughput per ip. The throughput will be divided amongst the concurrent connections per ip.
  5. Once a certain amount of bytes has been uploaded/downloaded drop the available throughput for a time period.
  6. Written in simple, easy to understand C.
  7. Add and remove headers for upstream and downstream connections

Let us look at a typical scenario below. One user has opened up a lot of connections to the server and is downloading or uploading a lot of data.


 The server now has less connections available for the other users and the most of the bandwidth is being used by the one greedy user. This usually results in a poor experience for other users.

Now we bring in the SpeedBump. This can be located on a seperate server or co-located with the existing server. For purposes of illustration let us show them on separate servers. Now all the connections have to first go through SpeedBump before they can get to the server.

SpeedBump will now reject all connections above the connection limit and throttle the bandwidth used by the greedy user. This reduces the load on the web/proxy server and gives a consistent experience to all the users.

    Software Maintained by TidyTutorials

    Here is a list of the software currently maintained by TidyTutorials.

    Free IP:Port Proxy Emulator
    This emulates the behaviour of an ip:port or elite proxy, but is written in php and runs inside an Apache web server. The only ip:port proxy emulator able to push rated advertisements! Contains Turing Test. The source code and installation instruction can be found at Project Mugatiya.
    Basic requirement is apache + php + should be able to configure .htaccess.
    Hosting : VPS/VDS


    Free Web Proxy
    Yet another web proxy such as Glype or PHProxy. Display advertisements and has the ability do display rated advertisements. Has unique ability to be rented out! The source code and installation instruction can be found at Project Uguduwa.
    Basic requirement is apache + php + shoulb be able to configure .htaccess.
    Hosting: Shared or VPS/VDS


    Free SpeedBump Software
    SpeedBump runs in front of a proxy server or web server and regulates connections and throttles bandwitdh. Don't let a single IP hog all your connections and bandwith. Set max concurrent connections per ip, max burst and average connections per ip, througput per ip and many more. Can be modified to be used as a proxy. The source code and installation instruction can be found at Project Kimbula.
    Basic requriement gcc/g++
    Hosing: VPS/VDS


    Common Database Pool Template
    A common database pool using a template that will support Oracle, MySQL and SQLServer and use as common a process and methodology as possible to access connections. More information can be found here

    Tracing Memory Leak in C/C++ Using Mtrace

    Aim
    The aim of this tutorial is to show how you how to trace a memory leak in a C/C++ program using mcheck. This allows you to match your malloc, realloc, calloc etc to your frees. Mtrace functionality is available with the gnu C/C++ dev packages.

    Let us take a look at the sample program below. Let's call this file leaker.c
     1. #include <stdlib.h>
     2. 
     3. #include <mcheck.h>
     4. 
     5. 
     6. int main(int argv, char** argc){
     7.         mtrace();
     8.         char * c1 = malloc(10*sizeof(char));
     9.         char * c2 = malloc(10*sizeof(char));
    10. 
    11.         c1[2]='a';
    12.         c2[2]='b';
    13. 
    14.         free(c2);
    15. 
    16.         muntrace();
    17. }
    Hide line numbers

    Line 3 You need to include the mcheck.h header file

    Line 7 call mtrace() to start the tracing.

    Line 16 call muntrace to stop the tracing.

    As you can see this program has a blatant memory leak, in that we are not freeing pointer C2. Next we have to compile the program with the -g switch so that we can find out at which line the leak is occurring.


    gcc -g leaker.c

    This will create the default a.out executable. Before we run the program we need to set an environment variable called MALLOC_TRACE. This will contain the location of the tracefile to be created by mtrace/mcheck. The example below is for the bash shell.


    >MALLOC_TRACE=/home/righteous/mt.txt

    Now we run the program. Once the program has run it's course you can take a look at the trace file that it has created.

    >./a.out
    >
    >cat mt.txt
    = Start
    @ ./a.out:[0x8048456] + 0x8968378 0xa
    @ ./a.out:[0x8048465] + 0x8968388 0xa
    @ ./a.out:[0x8048485] - 0x8968388
    = End

    To make sense of this file we need a perl script called mtrace.pl. This may or may not be available in your environment. You can search for the script and download it.
    Now we run the script and you will see details of the memory leak below.

    >perl mtrace.pl a.out mt.txt

    Memory not freed:
    -----------------
    Address Size Caller
    0x08968378 0xa at /home/test.c:8 ??:0


    Things get a lot trickier in an environment where you are forking process. For instance if you allocate memory, fork and then delete the memory in the child process, this will be flagged as an error as the child never actually allocated the memory. Also if you start mtrace after you have allocated memory or call muntrace before you have freed all your memory, mtrace will highlight these as errors.