Note that there are some explanatory texts on larger screens.

plurals
  1. POC: epoll port forwarding proxy doesn't forward all data
    primarykey
    data
    text
    <p>I have got this code and I'm trying to use it as a part of my project. The details of the project are not important for now, but what I'm trying to do is to use this port forwarding proxy as proxy between the browser and the local http server.</p> <p>So if I type http: //127.0.0.1:8999/ in my browser I want to get web page from 127.0.0.1:8888 back. This only works for small web pages (no images, small html files,...). When I try to do this on webpage with a few images, they don't get transmitted or are transmitted only partially.</p> <p>I have also tested with telnet and a web site with a big html file. I have connected to the proxy and send the HEAD method request. I got all the meta-data, as expected. When I tried GET method I got only part of the web page's html file back.</p> <p>Could anyone point me in the right direction? I'm really not sure what I am doing wrong.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/socket.h&gt; #include &lt;netdb.h&gt; #include &lt;unistd.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/epoll.h&gt; #include &lt;errno.h&gt; #include &lt;signal.h&gt; #include &lt;assert.h&gt; #define FALSE 0 #define TRUE 1 #define EPOLL_QUEUE_LEN 256 #define SERVER_PORT 7000 #define LISTEN_PORT 8667 // Proxy Server Listens for this port #define FORWARD_PORT 8888 // Proxy Server forwards all port LISTEN_PORT data to this port #define BUFLEN 1024 //Globals int fd_server; int sent = 0; // for how many requests were processed to client int forwardSockets[EPOLL_QUEUE_LEN]; int internalSockets[EPOLL_QUEUE_LEN]; // Function prototypes static void SystemFatal (const char* message); static int forwardData (int fd); void close_fd (int); // This is the main function which handles the epoll loop and // accepts connections // Also handles the data processing back to the client. int main (int argc, char* argv[]) { int i, arg, src_port, forwardSD, dest_port; int num_fds, fd_new, epoll_fd; int linenum=0; static struct epoll_event events[EPOLL_QUEUE_LEN], event; struct sockaddr_in addr, remote_addr; socklen_t addr_size = sizeof(struct sockaddr_in); struct sigaction act; struct hostent *hp; struct sockaddr_in server_fwd; char *host; char line[256], ip[256]; FILE *fp; fp=fopen("port_forward_config", "r"); //src_port = LISTEN_PORT; // Use the default listen port while(fgets(line, 256, fp) != NULL) { linenum++; if(line[0] == '#') continue; sscanf(line, "%s %d %d", &amp;ip, &amp;src_port, &amp;dest_port); { fprintf(stderr, "Syntax error, line %d\n", linenum); continue; } } printf("Reading Config File...\n"); printf("IP %s LPORT %d DPORT %d\n", ip, src_port, dest_port); host = ip; // set up the signal handler to close the server socket when CTRL-c is received act.sa_handler = close_fd; act.sa_flags = 0; if ((sigemptyset (&amp;act.sa_mask) == -1 || sigaction (SIGINT, &amp;act, NULL) == -1)) { perror ("Failed to set SIGINT handler"); exit (EXIT_FAILURE); } //-------------------------------------------------------------------------------------------- // Create the listening socket fd_server = socket (AF_INET, SOCK_STREAM, 0); if (fd_server == -1) { SystemFatal("socket"); } // set SO_REUSEADDR so port can be resused imemediately after exit, i.e., after CTRL-c arg = 1; if (setsockopt (fd_server, SOL_SOCKET, SO_REUSEADDR, &amp;arg, sizeof(arg)) == -1) { SystemFatal("setsockopt"); } // Make the server listening socket non-blocking if (fcntl (fd_server, F_SETFL, O_NONBLOCK | fcntl (fd_server, F_GETFL, 0)) == -1) { SystemFatal("fcntl"); } // Bind to the specified listening port memset (&amp;addr, 0, sizeof (struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(src_port); if (bind (fd_server, (struct sockaddr*) &amp;addr, sizeof(addr)) == -1) { SystemFatal("bind"); } // Listen for fd_news; SOMAXCONN is 128 by default if (listen (fd_server, SOMAXCONN) == -1) { SystemFatal("listen"); } //--------------------------------------------------------------------------------------------- // Create the epoll file descriptor epoll_fd = epoll_create(EPOLL_QUEUE_LEN); if (epoll_fd == -1) { SystemFatal("epoll_create"); } // Add the server socket to the epoll event loop event.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLET; event.data.fd = fd_server; if (epoll_ctl (epoll_fd, EPOLL_CTL_ADD, fd_server, &amp;event) == -1) { SystemFatal("epoll_ctl"); } // Execute the epoll event loop while (TRUE) { //struct epoll_event events[MAX_EVENTS]; num_fds = epoll_wait (epoll_fd, events, EPOLL_QUEUE_LEN, -1); if (num_fds &lt; 0) { SystemFatal ("Error in epoll_wait!"); } for (i = 0; i &lt; num_fds; i++) { // Case 1: Error condition if (events[i].events &amp; (EPOLLHUP | EPOLLERR)) { fputs("epoll: EPOLLERR", stderr); //close(events[i].data.fd); continue; } assert (events[i].events &amp; EPOLLIN); //----------------------------------------------------------------------------------------- // Case 2: Server is receiving a connection request if (events[i].data.fd == fd_server) { //socklen_t addr_size = sizeof(remote_addr); fd_new = accept (fd_server, (struct sockaddr*) &amp;remote_addr, &amp;addr_size); if (fd_new == -1) { if (errno != EAGAIN &amp;&amp; errno != EWOULDBLOCK) { perror("accept"); } continue; } //------------------------------------------------------------------------------------------------ // Make the fd_new non-blocking if (fcntl (fd_new, F_SETFL, O_NONBLOCK | fcntl(fd_new, F_GETFL, 0)) == -1) { SystemFatal("fcntl"); } // Add the new socket descriptor to the epoll loop event.data.fd = fd_new; if (epoll_ctl (epoll_fd, EPOLL_CTL_ADD, fd_new, &amp;event) == -1) { SystemFatal ("epoll_ctl"); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ printf(" Remote Address: %s\n", inet_ntoa(remote_addr.sin_addr)); //close(fd_new); dest_port = FORWARD_PORT; // Used the default forward port // create internal connection printf("Trying to create forward socket\n"); if ((forwardSD = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Cannot create forward socket."); exit(1); } printf("Binding...\n"); bzero((char *)&amp;server_fwd, sizeof(struct sockaddr_in)); server_fwd.sin_family = AF_INET; server_fwd.sin_port = htons(dest_port); //host = "192.168.0.10"; if ((hp = gethostbyname(host)) == NULL) { printf("Failed to get host name"); } bcopy(hp-&gt;h_addr, (char *)&amp;server_fwd.sin_addr, hp-&gt;h_length); printf("Connecting to interal machine.\n"); printf("Server Forward Port: %d\n", ntohs(server_fwd.sin_port)); printf("Server Forward IP: %s\n", inet_ntoa(server_fwd.sin_addr)); // Connecting to interal machine if (connect (forwardSD, (struct sockaddr *)&amp;server_fwd, sizeof(server_fwd)) == -1) { perror("connect failed"); exit(1); } // Add the new socket descriptor to the epoll loop event.data.fd = forwardSD; if (epoll_ctl (epoll_fd, EPOLL_CTL_ADD, forwardSD, &amp;event) == -1) { SystemFatal ("epoll_ctl"); } printf ("Connected: Server: %s\n", hp-&gt;h_name); forwardSockets[fd_new] = forwardSD; internalSockets[forwardSD] = fd_new; // end internal connection //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ continue; } // Case 3: One of the sockets has read data if (!forwardData(events[i].data.fd)) { // epoll will remove the fd from its set // automatically when the fd is closed close (events[i].data.fd); } } } close(fd_server); exit (EXIT_SUCCESS); } /* This function clears a socket if it has data waiting to be processed. It takes the string sent from the client and parses it. After it has done that it will send back to the client the amount of data it requested for however many requests it defined as well. */ static int forwardData (int fd) { int n, bytes_to_read; char *bp, buf[BUFLEN]; int forwardData; printf ("Forwarding :\n"); //check if internal or external connection to send data back to. if(forwardSockets[fd] != 0){ forwardData = forwardSockets[fd]; } if(internalSockets[fd] != 0){ forwardData = internalSockets[fd]; } bp = buf; bytes_to_read = BUFLEN; while ((n = recv (fd, bp, bytes_to_read, 0)) &gt; 0) { bp += n; bytes_to_read -= n; send (forwardData, buf, n, 0); return TRUE; } return TRUE; } // Prints the error stored in errno and aborts the program. static void SystemFatal(const char* message) { perror (message); exit (EXIT_FAILURE); } // close fd void close_fd (int signo) { close(fd_server); exit (EXIT_SUCCESS); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload