/* Socks Server 5
* Copyright (C) 2002 - 2006 by Matteo Ricchetti - <matteo.ricchetti@libero.it>
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* B
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include"SS5Main.h"
#include"SS5Defs.h"
#include"SS5Mod_proxy.h"
S5RetCode InitModule( struct _module *m )
{
m->ReceivingData = ReceivingData;
m->SendingData = SendingData;
m->UdpReceivingData = UdpReceivingData;
m->UdpSendingData = UdpSendingData;
return OK;
}
S5RetCode
IFEPOLL( ReceivingData( struct _SS5ClientInfo *ci, int applicationSocket, struct _SS5ProxyData *pd, struct epoll_event *events ) )
IFSELECT( ReceivingData( struct _SS5ClientInfo *ci, int applicationSocket, struct _SS5ProxyData *pd, fd_set *s5array ) )
{
/*
* Receive data from client
*/
IFEPOLL( if( events[0].data.fd == ci->Socket ) { )
IFSELECT( if( FD_ISSET(ci->Socket,s5array) ) { )
memset(pd->Recv,0,sizeof(pd->Recv));
pd->TcpRBufLen = recv(ci->Socket,pd->Recv,sizeof(pd->Recv),0);
pd->Fd = 0;
}
/*
* Receive data from application
*/
IFEPOLL( else if( events[0].data.fd == applicationSocket ) { )
IFSELECT( else if( FD_ISSET(applicationSocket,s5array) ) { )
memset(pd->Recv,0,sizeof(pd->Recv));
pd->TcpRBufLen = recv(applicationSocket,pd->Recv,sizeof(pd->Recv),0);
pd->Fd = 1;
}
return OK;
}
S5RetCode
SendingData( struct _SS5ClientInfo *ci, int applicationSocket, struct _SS5ProxyData *pd )
{
if( pd->Fd == 1 ) {
memset(pd->Send,0,sizeof(pd->Send));
memcpy(pd->Send,pd->Recv,pd->TcpRBufLen);
pd->TcpSBufLen = send(ci->Socket,pd->Send,pd->TcpRBufLen,SS5_SEND_OPT);
}
else {
memset(pd->Send,0,sizeof(pd->Send));
memcpy(pd->Send,pd->Recv,pd->TcpRBufLen);
pd->TcpSBufLen = send(applicationSocket,pd->Send,pd->TcpRBufLen,SS5_SEND_OPT);
}
return OK;
}
S5RetCode
UdpReceivingData( int applicationSocket, struct _SS5ProxyData *pd )
{
unsigned int len;
unsigned int fd;
struct timeval tv;
fd_set arrayFd;
struct sockaddr_in applicationSsin;
char logString[128];
pid_t pid;
/*
* Get child/thread pid
*/
if( NOTTHREADED() )
pid=getpid();
else
pid=(unsigned int)pthread_self();
bzero((char *)&applicationSsin, sizeof(struct sockaddr_in));
len = sizeof(struct sockaddr_in);
memset(pd->UdpRecv,0,sizeof(pd->UdpRecv));
FD_ZERO(&arrayFd);
FD_SET(applicationSocket,&arrayFd);
tv.tv_sec = UDP_TIMEOUT;
tv.tv_usec = 0;
if( (fd = select(applicationSocket+1,&arrayFd,NULL,NULL,&tv)) ) {
if( FD_ISSET(applicationSocket,&arrayFd) ) {
if( (pd->UdpRBufLen=recvfrom(applicationSocket,pd->UdpRecv,sizeof(pd->UdpRecv),0,(struct sockaddr *)&applicationSsin,(socklen_t *)&len)) == -1 ) {
ERRNO(pid)
return ERR;
}
}
}
else {
/*
* Timeout expired receiving data from remote application
*/
return (-1 * S5REQUEST_TTLEXPIRED);
}
return OK;
}
S5RetCode
UdpSendingData( int applicationSocket, struct _SS5UdpRequestInfo *uri , struct _SS5ProxyData *pd )
{
unsigned int len;
char logString[128];
pid_t pid;
struct sockaddr_in applicationSsin;
/*
* Get child/thread pid
*/
if( NOTTHREADED() )
pid=getpid();
else
pid=(unsigned int)pthread_self();
len = sizeof(struct sockaddr_in);
memset((char *)&applicationSsin, 0, sizeof(struct sockaddr_in));
applicationSsin.sin_family = AF_INET;
applicationSsin.sin_port = htons(uri->DstPort);
applicationSsin.sin_addr.s_addr = inet_addr(uri->DstAddr);
if( (pd->UdpSBufLen=sendto(applicationSocket,pd->UdpSend,pd->UdpSBufLen,0,(struct sockaddr *)&applicationSsin,(socklen_t)len)) == -1 ) {
ERRNO(pid)
return ERR;
}
return OK;
}
syntax highlighted by Code2HTML, v. 0.9.1