一些代理的连接方法:socks4,socks5,https,http
框架。
http://www.socks.nec.com/protocol/socks4.protocol
http://www.socks.nec.com/protocol/socks4a.protocol
//里面的原代码均是选自于miranda32这个开源项目中的。
//代理服务器的代码推荐大家去学习oops-1.5.22里面的,这也是个开源项目。
int NetlibOpenConnection(WPARAM wParam,LPARAM lParam)
{
NETLIBOPENCONNECTION *nloc=(NETLIBOPENCONNECTION*)lParam;
struct NetlibUser *nlu=(struct NetlibUser*)wParam;
struct NetlibConnection *nlc;
SOCKADDR_IN sin;
if(GetNetlibHandleType(nlu)!=NLH_USER || !(nlu->user.flags&NUF_OUTGOING) || nloc==NULL || nloc->cbSize!=sizeof(NETLIBOPENCONNECTION) || nloc->szHost==NULL || nloc->wPort==0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return (int)(HANDLE)NULL;
}
nlc=(struct NetlibConnection*)calloc(1,sizeof(struct NetlibConnection));
nlc->handleType=NLH_CONNECTION;
nlc->nlu=nlu;
nlc->s=socket(AF_INET,SOCK_STREAM,0);
if(nlc->s==INVALID_SOCKET)
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError());
free(nlc);
return (int)(HANDLE)NULL;
}
if (nlu->settings.szIncomingPorts)
{
BYTE portsMask[0x2000];
int startPort,portNum,i,j,portsCount;
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(INADDR_ANY);
sin.sin_port=0;
portsCount=StringToPortsMask(nlu->settings.szIncomingPorts,portsMask);
if (portsCount)
{
startPort=rand()&portsCount;
for (i=0;i<0x02000;i++)
{
if(portsMask[i]==0) continue;
if(portsMask[i]==0xFF && startPort>=8) {startPort-=8; continue;}
for(j=0;j<8;j++)
if(portsMask[i]&(1<<j))
if(startPort--==0)
{
portNum=(i<<3)+j;
break;
}
if(startPort==-1) break;
} //for
if (i!=0x2000)
{
startPort=portNum;
do
{
sin.sin_port=htons((WORD)portNum);
if(bind(nlc->s,(SOCKADDR*)&sin,sizeof(sin))==0) break;
for(portNum++;!PortInMask(portsMask,portNum);portNum++)
if(portNum==0xFFFF) portNum=0;
} while (portNum!=startPort);
} //if
} //if
}
InitializeCriticalSection(&nlc->csHttpSequenceNums);
nlc->hOkToCloseEvent=CreateEvent(NULL,TRUE,TRUE,NULL);
nlc->dontCloseNow=0;
NetlibInitializeNestedCS(&nlc->ncsSend);
NetlibInitializeNestedCS(&nlc->ncsRecv);
if(nlu->settings.useProxy && (nlu->settings.proxyType==PROXYTYPE_HTTP || nlu->settings.proxyType==PROXYTYPE_HTTPS) && nlu->settings.useProxyAuth && nlu->settings.useProxyAuthNtlm)
nlc->hInstSecurityDll=LoadLibrary("security.dll");
nlc->sinProxy.sin_family=AF_INET;
if(nlu->settings.useProxy)
{
nlc->sinProxy.sin_port=htons((short)nlu->settings.wProxyPort);
nlc->sinProxy.sin_addr.S_un.S_addr=DnsLookup(nlu,nlu->settings.szProxyServer);
}
else
{
nlc->sinProxy.sin_port=htons((short)nloc->wPort);
nlc->sinProxy.sin_addr.S_un.S_addr=DnsLookup(nlu,nloc->szHost);
}
if(nlc->sinProxy.sin_addr.S_un.S_addr==0
|| connect(nlc->s,(SOCKADDR *)&nlc->sinProxy,sizeof(nlc->sinProxy))==SOCKET_ERROR)
{
if(nlc->sinProxy.sin_addr.S_un.S_addr)
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"connect",WSAGetLastError());
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
if(nlu->settings.useProxy
&& !(nloc->flags&NLOCF_HTTP
&& (nlu->settings.proxyType==PROXYTYPE_HTTP || nlu->settings.proxyType==PROXYTYPE_HTTPS)))
{
if(!WaitUntilWritable(nlc->s,30000))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
switch(nlu->settings.proxyType)
{
case PROXYTYPE_SOCKS4:
//socks4代理的连接,直接调用NetlibInitSocks4Connection
if(!NetlibInitSocks4Connection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;
case PROXYTYPE_SOCKS5:
//socks5代理的连接,直接调用NetlibInitSocks5Connection
if(!NetlibInitSocks5Connection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;
case PROXYTYPE_HTTPS:
//https代理连接,直接调用NetlibInitHttpsConnection
if(!NetlibInitHttpsConnection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;
case PROXYTYPE_HTTP:
//http代理连接
if(!(nlu->user.flags&NUF_HTTPGATEWAY))
{
//NLOCF_HTTP not specified and no HTTP gateway available: try HTTPS
if(!NetlibInitHttpsConnection(nlc,nlu,nloc))
{
//can't do HTTPS: try direct
if(nlc->s!=INVALID_SOCKET) closesocket(nlc->s);
nlc->s=socket(AF_INET,SOCK_STREAM,0);
if(nlc->s==INVALID_SOCKET)
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
nlc->sinProxy.sin_family=AF_INET;
nlc->sinProxy.sin_port=htons((short)nloc->wPort);
nlc->sinProxy.sin_addr.S_un.S_addr=DnsLookup(nlu,nloc->szHost);
if(nlc->sinProxy.sin_addr.S_un.S_addr==0
|| connect(nlc->s,(SOCKADDR *)&nlc->sinProxy,sizeof(nlc->sinProxy))==SOCKET_ERROR)
{
if(nlc->sinProxy.sin_addr.S_un.S_addr)
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"connect",WSAGetLastError());
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
}
}
else if(!NetlibInitHttpConnection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
}
Netlib_Logf(nlu,"(%d) Connected to %s:%d",nlc->s,nloc->szHost,nloc->wPort);
return (int)nlc;
}