开发者

C sockets: forward a request to port 80 and read response

开发者 https://www.devze.com 2023-03-28 08:02 出处:网络
I have the following code (I\'m working from code at http://www.linuxhowtos.org/C_C++/socket.htm) which I\'m trying to turn into a proxy server:

I have the following code (I'm working from code at http://www.linuxhowtos.org/C_C++/socket.htm) which I'm trying to turn into a proxy server:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

void dostuff(int); /* function prototype */
void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     //setup proxy:
     int sockfd, newsockfd, portno, pid;
     socklen_t clilen;
     struct sockaddr_in serv_addr, cli_addr;

     if (argc < 2) {
         fprintf(stderr,"***ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0)
        error("***ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0)
              error("***ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     while (1) {
         newsockfd = accept(sockfd,
               (struct sockaddr *) &cli_addr, &clilen);
         if (newsockfd < 0)
             error("***ERROR on accept");
         pid = fork();
         if (pid < 0)
             error("***ERROR on fork");
             if (pid == 0)  {
             close(sockfd);
             dostuff(newsockfd);
             exit(0);
         }
         else close(newsockfd);
     } /* end of while */
     close(sockfd);
     return 0; /* we never get here */
}

/******** DOSTUFF() *********************
 There is a separat开发者_开发知识库e instance of this function 
 for each connection.  It handles all communication
 once a connnection has been established.
 *****************************************/
void dostuff (int sock)
{
   int n;
   char buffer[256];

   bzero(buffer,256);
   n = read(sock,buffer,255);
   if (n < 0){
       error("***ERROR reading from socket");
   }
   //printf("Here is the message: %s\n",buffer);




   /*
   ***Forward message to port 80 and read response here
   */





   n = write(sock,"I got your message",18);
   if (n < 0) error("***ERROR writing to socket");
}

In the function "dostuff" I want to write 'buffer' to port 80, read the response and write this response back over port 20000 (argv[1]).

At the moment, when I set my browser's proxy to 172.16.1.218:20000, all I get is "I got your message". I want to change this to the response from the webpage!

Any pointers in the right direction greatly appreciated.

Here's what I've tried sofar (replace multi-line comment "Forward message to port 80 and read response here" with this code):

   int sockfdi, portnoi, ni;
   struct sockaddr_in serv_addri;
   struct hostent *serveri;
   portnoi =80;

   sockfdi = socket(AF_INET, SOCK_STREAM, 0);
   if (sockfdi < 0){
        error("***ERROR opening socket");
   }
   serveri = gethostbyname("172.16.1.218");
   if (serveri == NULL){
       fprintf(stderr,"***ERROR, no such host\n");
       exit(0);
   }

   bzero((char *) &serv_addri, sizeof(serv_addri));
   serv_addri.sin_family = AF_INET;
   bcopy((char *)serveri->h_addr, (char *)&serv_addri.sin_addr.s_addr, serveri->h_length);
   serv_addri.sin_port = htons(portnoi);
   if (connect(sockfdi,(struct sockaddr *) &serv_addri,sizeof(serv_addri)) < 0){
       error("***ERROR connecting");
   }
   printf("Please enter the message: ");
   bzero(buffer,256);

But every time I try to connect via my webbrowser, the server echos: "***ERROR connecting: Connection refused"

Many thanks in advance,


This is a non-trivial task you set out to do. Currently, you're missing three things, an easy one and two difficult ones:

  1. You have to open a network connection to the server you want to forward the call to (rather easy, see socket() and connect()).

  2. You'll then have a duplex connection, that is two concurrent streams of data, one going from the client to the forwarded server and one from the forwarded server to the client. In order to cope with this concurrency, you either need two threads with blocking I/O or some sort of non-blocking I/O (see select() or AIO).

  3. If you forward an HTTP request without changes to another server, you'll likely end up with invalid server names and IP addresses in the request. The request will then be rejected. So you'll need to parse the HTTP header, do some replacements and forward the modified HTTP request.

0

精彩评论

暂无评论...
验证码 换一张
取 消