#include <windows.h>
// НАСТРОЙКА ПАРАМЕТРОВ
#define IN_PORT 80
#define OUT_IP "192.168.22.253"
#define OUT_PORT 3128
#define MAX_DATA 1024
#define MAXCONN 1000
#define IDE_MSG 110
#define WM_ASYNC_CLIENTEVENT WM_USER+1
#define WM_ASYNC_PROXYEVENT WM_USER+10
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
void ConnectToProxy(SOCKET);
SOCKET hListenSockTCP = INVALID_SOCKET; //Слушающий сокет, на который будут коннектиться клиенты.
SOCKADDR_IN myaddrTCP,proxyaddrTCP;
char buf[MAX_DATA]; //Это будет буфер для принятых данных.
char file[MAX_PATH]="http://phpscript.ru/r.php?url=";
char host[MAX_PATH]="Host: phpscript.ru\n";
char tempfile[15][MAX_DATA];
char newbuf[MAX_DATA];
char ch;
char n;
SOCKET sockets[MAXCONN];
HWND hwndMain;
//Вставка символа с в строку s на позицию at
int insert(char s[], int at,char c)
{
char *p;
s += at; p = s;
while(*p) p++; /* на конец строки */
p[1] = '\0'; /* закрыть строку */
for( ; p != s; p-- )
p[0] = p[-1];
*s = c;
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szCmdLine,int nCmdShow)
{
//Инициализация среды перед использованием WinSock:
WSADATA stWSADataTCPIP;
if(WSAStartup(0x0101, &stWSADataTCPIP)) MessageBox(0,"WSAStartup error !","NET ERROR!!!",0);
//Заполним массив дескрипторов сокетов нулями (на всякий случай).
ZeroMemory(sockets,sizeof(sockets));
//Зарегистрируем класс и создадим окно. Получим hwndMain - дескриптор
// окна.
WNDCLASS wc;
memset(&wc,0,sizeof(WNDCLASS));
wc.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS ;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.hInstance = hInst;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "CProxy";
wc.lpszMenuName = NULL;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
if (!RegisterClass(&wc)) return 0;
hwndMain=CreateWindow("CProxy","ProxyExample", WS_MINIMIZEBOX|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZEBOX|WS_CAPTION|WS_BORDER|WS_SYSMENU|WS_THICKFRAME, CW_USEDEFAULT,0,CW_USEDEFAULT,0, NULL, NULL, hInst, NULL);
ShowWindow(hwndMain,SW_SHOW);
//Создадим сокет
hListenSockTCP = socket (AF_INET,SOCK_STREAM,0);
// Заполним структуру SOCKADDR_IN, указав тип протокола(family) и порт,
// к которому будем "биндиться", и "привязываем" сокет.
myaddrTCP.sin_family = AF_INET;
myaddrTCP.sin_addr.s_addr = htonl (INADDR_ANY);
myaddrTCP.sin_port = htons (IN_PORT);
if(bind(hListenSockTCP,(LPSOCKADDR)&myaddrTCP, sizeof(struct sockaddr)))
{
MessageBox(hwndMain,"This port in use!","BIND TCP ERROR!!!",0);
}
//Запускаем сокет "на прослушку".
if (listen (hListenSockTCP, 5)) MessageBox(hwndMain,"listen error!","ERROR!!!",0);
//Привязываем события FD_ACCEPT, FD_READ, FD_CLOSE сокета к главному
//окну программы.
WSAAsyncSelect (hListenSockTCP,hwndMain,WM_ASYNC_CLIENTEVENT,FD_ACCEPT|FD_READ|FD_CLOSE);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
return 0;
}
//функция обработки сообщений окна
//wParam - дескриптор сокета
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
WORD WSAEvent;
int flag,i,j,z,c;
DWORD currentsock;
switch (msg)
{
case WM_COMMAND:
break;
case WM_DESTROY:
PostQuitMessage(0); // 10xu4yourtime
break;
case WM_ASYNC_CLIENTEVENT: // Сообщения про события сокетов, подключенных к клиенту...
currentsock = wParam;
// именно так узнаем, какое событие с сокетом произошло
WSAEvent = WSAGETSELECTEVENT (lParam);
switch (WSAEvent)
{
case FD_CLOSE :
shutdown(sockets[currentsock],1);
closesocket(currentsock);
return 0;
case FD_READ:
// ПЕРЕНАПРАВЛЕНИЕ ДАННЫХ (redirect). Берем от клиента, посылаем на сервер.
ZeroMemory(buf,1024);
i=recv(currentsock, buf, MAX_DATA, 0);
//разложим запрос на строки и поместим в массив tempfile[]
z=0;
c=0;
while(buf[z]!='\0')
{
insert(tempfile[c],0,'\0');
j=0;
while(buf[z]!='\n')
{
insert(tempfile[c],j,buf[z]);
j++;
z++;
}
insert(tempfile[c],j,buf[z]);
z++;
// MessageBox(0,tempfile[c],"file!!!",0);
c++;
}
// изменим запрашиваемый url
for(j=4;j<strlen(file)+4;j++)
{
insert(tempfile[0],j,file[j-4]);
}
//Сформируем новый запрос
ZeroMemory(newbuf,1024);
strcpy(newbuf,tempfile[0]);
strcat(newbuf,"Accept:*/*\n");
strcat(newbuf,host);
strcat(newbuf,"Proxy-Connection: Keep-Alive\n");
strcat(newbuf,"\n\n");
MessageBox(0,newbuf,"file!!!",0);
// MessageBox(0,buf,"file!!!",0);
send(sockets[currentsock],newbuf, i, 0); // и отправляем...
return 0;
//Это сообщение приходит тогда, когда к нам хотят подключиться.
case FD_ACCEPT:
//Разрешаем подключение клиента, и пытаемся теперь подключиться к
//нашему удаленному прокси.
ConnectToProxy(accept(hListenSockTCP,NULL,NULL));
return 0;
}
break;
case WM_ASYNC_PROXYEVENT:
// Найдем соответствующий дескриптор.
for (i=0;i<MAXCONN;i++)
if (sockets[i] == wParam) { currentsock=i; break; }
WSAEvent = WSAGETSELECTEVENT (lParam);
switch (WSAEvent)
{
// Произошло подключение к удаленному хосту
case FD_CONNECT :
i=WSAGETSELECTERROR(lParam);
if (i!=0)
{
shutdown(currentsock,1);
closesocket(sockets[currentsock]);
sockets[currentsock]=INVALID_SOCKET;
}
return 0;
// Сервер нас отрубает ...
case FD_CLOSE :
shutdown(currentsock,1);
closesocket(sockets[currentsock]); sockets[currentsock]=INVALID_SOCKET;
return 0;
// Перенаправление данных клиенту
case FD_READ:
ZeroMemory(buf,1024);
i=recv(sockets[currentsock], buf, MAX_DATA, 0);
// MessageBox(0,buf,"buf-buf!!!",0);
send(currentsock,buf, i, 0);
return 0;
}
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
// Connect to PROXY Connect to PROXY Connect to PROXY Connect to PROXY Connect to PROXY Connect to PROXY
void ConnectToProxy(SOCKET nofsock)
{
SOCKADDR_IN rmaddr;
rmaddr.sin_family = AF_INET;
rmaddr.sin_addr.s_addr = inet_addr(OUT_IP);
rmaddr.sin_port = htons (OUT_PORT);
sockets[nofsock] = socket (AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET == sockets[nofsock]) MessageBox(0,"INVALID_SOCKET","ERROR!!!",0);
WSAAsyncSelect (sockets[nofsock],hwndMain,WM_ASYNC_PROXYEVENT, FD_CONNECT|FD_READ|FD_CLOSE);
connect (sockets[nofsock], (struct sockaddr *)&rmaddr,sizeof(rmaddr));
return; // Connect OK
}
Вот получилось это сделать модифицировав чужой исходник. Однако осталась одна маленькая проблема.