📄 socks.cxx
字号:
port = localPort;
return TRUE;
}
BOOL PSocksSocket::Accept()
{
if (!IsOpen())
return FALSE;
return ReceiveSocksResponse(*this, remoteAddress, remotePort);
}
BOOL PSocksSocket::Accept(PSocket & socket)
{
// If is right class, transfer the SOCKS socket to class to receive the accept
// The "listener" socket is implicitly closed as there is really only one
// handle in a SOCKS BIND operation.
PAssert(PIsDescendant(&socket, PSocksSocket), PUnsupportedFeature);
os_handle = ((PSocksSocket &)socket).TransferHandle(*this);
return Accept();
}
int PSocksSocket::TransferHandle(PSocksSocket & destination)
{
// This "transfers" the socket from one onstance to another.
int the_handle = os_handle;
destination.SetReadTimeout(readTimeout);
destination.SetWriteTimeout(writeTimeout);
// Close the instance of the socket but don't actually close handle.
os_handle = -1;
return the_handle;
}
BOOL PSocksSocket::GetLocalAddress(Address & addr)
{
if (!IsOpen())
return FALSE;
addr = localAddress;
return TRUE;
}
BOOL PSocksSocket::GetLocalAddress(Address & addr, WORD & port)
{
if (!IsOpen())
return FALSE;
addr = localAddress;
port = localPort;
return TRUE;
}
BOOL PSocksSocket::GetPeerAddress(Address & addr)
{
if (!IsOpen())
return FALSE;
addr = remoteAddress;
return TRUE;
}
BOOL PSocksSocket::GetPeerAddress(Address & addr, WORD & port)
{
if (!IsOpen())
return FALSE;
addr = remoteAddress;
port = remotePort;
return TRUE;
}
void PSocksSocket::SetErrorCodes(PChannel::Errors errCode, int osErr)
{
SetErrorValues(errCode, osErr);
}
///////////////////////////////////////////////////////////////////////////////
PSocks4Socket::PSocks4Socket(WORD port)
: PSocksSocket(port)
{
}
PSocks4Socket::PSocks4Socket(const PString & host, WORD port)
: PSocksSocket(port)
{
Connect(host);
}
PObject * PSocks4Socket::Clone() const
{
return new PSocks4Socket(remotePort);
}
BOOL PSocks4Socket::SendSocksCommand(PTCPSocket & socket,
BYTE command,
const char * hostname,
Address addr)
{
if (hostname != NULL) {
if (!GetHostAddress(hostname, addr))
return FALSE;
}
if (!IsOpen()) {
if (!ConnectSocksServer(*this))
return FALSE;
}
PString user = PProcess::Current().GetUserName();
socket << SOCKS_VERSION_4
<< command
<< (BYTE)(remotePort >> 8) << (BYTE)remotePort
<< addr.Byte1() << addr.Byte2() << addr.Byte3() << addr.Byte4()
<< user << ((BYTE)0)
<< ::flush;
return ReceiveSocksResponse(socket, localAddress, localPort);
}
BOOL PSocks4Socket::ReceiveSocksResponse(PTCPSocket & socket,
Address & addr,
WORD & port)
{
int reply;
if ((reply = socket.ReadChar()) < 0)
return FALSE;
if (reply != 0 /*!= SOCKS_VERSION_4*/) {
SetErrorCodes(PChannel::Miscellaneous, EINVAL);
return FALSE;
}
if ((reply = socket.ReadChar()) < 0)
return FALSE;
switch (reply) {
case 90 : // No error
break;
case 91 : // Connection refused
SetErrorCodes(PChannel::NotFound, EHOSTUNREACH);
return FALSE;
case 92 : // Refused permission
SetErrorCodes(PChannel::AccessDenied, EACCES);
return FALSE;
default :
SetErrorCodes(PChannel::Miscellaneous, EINVAL);
return FALSE;
}
WORD rxPort;
if (!socket.ReadBlock(&rxPort, sizeof(rxPort)))
return FALSE;
port = PSocket::Net2Host(rxPort);
in_addr add;
if ( socket.ReadBlock(&add, sizeof(add)) )
{
addr = add;
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
PSocks5Socket::PSocks5Socket(WORD port)
: PSocksSocket(port)
{
}
PSocks5Socket::PSocks5Socket(const PString & host, WORD port)
: PSocksSocket(port)
{
Connect(host);
}
PObject * PSocks5Socket::Clone() const
{
return new PSocks5Socket(remotePort);
}
///////////////////////////////////////////////////////////////////////////////
PSocksUDPSocket::PSocksUDPSocket(WORD port)
: PSocksProtocol(port)
{
}
PSocksUDPSocket::PSocksUDPSocket(const PString & host, WORD port)
: PSocksProtocol(port)
{
Connect(host);
}
PObject * PSocksUDPSocket::Clone() const
{
return new PSocksUDPSocket(port);
}
BOOL PSocksUDPSocket::Connect(const PString & address)
{
if (!SendSocksCommand(socksControl, SOCKS_CMD_UDP_ASSOCIATE, address, 0))
return FALSE;
socksControl.GetPeerAddress(serverAddress);
return TRUE;
}
BOOL PSocksUDPSocket::Connect(const Address & addr)
{
if (!SendSocksCommand(socksControl, SOCKS_CMD_UDP_ASSOCIATE, NULL, addr))
return FALSE;
socksControl.GetPeerAddress(serverAddress);
return TRUE;
}
BOOL PSocksUDPSocket::Connect(WORD, const Address &)
{
PAssertAlways(PUnsupportedFeature);
return FALSE;
}
BOOL PSocksUDPSocket::Listen(unsigned, WORD newPort, Reusability reuse)
{
PAssert(newPort == 0 && port == 0, PUnsupportedFeature);
PAssert(reuse, PUnsupportedFeature);
if (!SendSocksCommand(socksControl, SOCKS_CMD_UDP_ASSOCIATE, NULL, 0))
return FALSE;
socksControl.GetPeerAddress(serverAddress);
port = localPort;
return TRUE;
}
BOOL PSocksUDPSocket::GetLocalAddress(Address & addr)
{
if (!IsOpen())
return FALSE;
addr = localAddress;
return TRUE;
}
BOOL PSocksUDPSocket::GetLocalAddress(Address & addr, WORD & port)
{
if (!IsOpen())
return FALSE;
addr = localAddress;
port = localPort;
return TRUE;
}
BOOL PSocksUDPSocket::GetPeerAddress(Address & addr)
{
if (!IsOpen())
return FALSE;
addr = remoteAddress;
return TRUE;
}
BOOL PSocksUDPSocket::GetPeerAddress(Address & addr, WORD & port)
{
if (!IsOpen())
return FALSE;
addr = remoteAddress;
port = remotePort;
return TRUE;
}
BOOL PSocksUDPSocket::ReadFrom(void * buf, PINDEX len, Address & addr, WORD & port)
{
PBYTEArray newbuf(len+262);
Address rx_addr;
WORD rx_port;
if (!PUDPSocket::ReadFrom(newbuf.GetPointer(), newbuf.GetSize(), rx_addr, rx_port))
return FALSE;
if (rx_addr != serverAddress || rx_port != serverPort)
return FALSE;
PINDEX port_pos;
switch (newbuf[3]) {
case SOCKS_ADDR_DOMAINNAME :
if (!PIPSocket::GetHostAddress(PString((const char *)&newbuf[5], (PINDEX)newbuf[4]), addr))
return FALSE;
port_pos = newbuf[4]+5;
break;
case SOCKS_ADDR_IPV4 :
memcpy(&addr, &newbuf[4], 4);
port_pos = 4;
break;
default :
SetErrorCodes(PChannel::Miscellaneous, EINVAL);
return FALSE;
}
port = (WORD)((newbuf[port_pos] << 8)|newbuf[port_pos+1]);
memcpy(buf, &newbuf[port_pos+2], len);
return TRUE;
}
BOOL PSocksUDPSocket::WriteTo(const void * buf, PINDEX len, const Address & addr, WORD port)
{
PBYTEArray newbuf(len+10);
BYTE * bufptr = newbuf.GetPointer();
// Build header, bytes 0, 1 & 2 are zero
bufptr[3] = SOCKS_ADDR_IPV4;
memcpy(bufptr+4, &addr, 4);
bufptr[8] = (BYTE)(port >> 8);
bufptr[9] = (BYTE)port;
memcpy(bufptr+10, buf, len);
return PUDPSocket::WriteTo(newbuf, newbuf.GetSize(), serverAddress, serverPort);
}
void PSocksUDPSocket::SetErrorCodes(PChannel::Errors errCode, int osErr)
{
SetErrorValues(errCode, osErr);
}
// End of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -