/*
3APA3A simpliest proxy server
(c) 2002-2006 by ZARAZA <3APA3A@security.nnov.ru>
please read License Agreement
*/
#include "proxy.h"
#define BUFSIZE ((param->service == S_UDPPM)?UDPBUFSIZE:TCPBUFSIZE)
int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to){
int sent = 0;
int res;
struct pollfd fds;
fds.fd = sock;
fds.events = POLLOUT;
do {
if(timetoexit) return 0;
res = poll(&fds, 1, to*1000);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
res = send(sock, buf + sent, bufsize - sent, 0);
if(res < 0) {
if(errno == EAGAIN || errno == EINTR) continue;
break;
}
sent += res;
} while (sent < bufsize);
return sent;
}
int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){
int sent = 0;
int res;
struct pollfd fds;
fds.fd = sock;
do {
if(timetoexit) return 0;
fds.events = POLLOUT;
res = poll(&fds, 1, to);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
res = sendto(sock, buf + sent, bufsize - sent, 0, (struct sockaddr *)sin, sizeof(struct sockaddr_in));
if(res < 0) {
if(errno != EAGAIN) break;
continue;
}
sent += res;
} while (sent < bufsize);
return sent;
}
int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){
struct pollfd fds;
SASIZETYPE sasize;
int res;
fds.fd = sock;
fds.events = POLLIN;
if(timetoexit) return EOF;
if (poll(&fds, 1, to)<1) return 0;
sasize = sizeof(struct sockaddr_in);
do {
res = recvfrom(sock, buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
} while (res < 0 && (errno == EAGAIN || errno == EINTR));
return res;
}
int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){
int len;
if(!param->clibuf){
if(!(param->clibuf = myalloc(BUFSIZE))) return 0;
param->clibufsize = BUFSIZE;
param->clioffset = param->cliinbuf = 0;
}
if(param->cliinbuf && param->clioffset < param->cliinbuf){
return (int)param->clibuf[param->clioffset++];
}
param->clioffset = param->cliinbuf = 0;
if ((len = sockrecvfrom(param->clisock, ¶m->sinc, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
param->cliinbuf = len;
param->clioffset = 1;
return (int)*param->clibuf;
}
int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){
int len;
if(!param->srvbuf){
if(!(param->srvbuf = myalloc(BUFSIZE))) return 0;
param->srvbufsize = BUFSIZE;
param->srvoffset = param->srvinbuf = 0;
}
if(param->srvinbuf && param->srvoffset < param->srvinbuf){
return (int)param->srvbuf[param->srvoffset++];
}
param->srvoffset = param->srvinbuf = 0;
if ((len = sockrecvfrom(param->remsock, ¶m->sins, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
param->srvinbuf = len;
param->srvoffset = 1;
return (int)*param->srvbuf;
}
int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to){
int c;
int i=0, tos, tou;
if(bufsize<2) return 0;
c = (which)?sockgetcharsrv(param, to, 0):sockgetcharcli(param, to, 0);
if (c == EOF) {
return 0;
}
tos = to/16;
tou = ((to * 1000) / bufsize)%1000;
do {
buf[i++] = c;
if(delim != EOF && c == delim) break;
}while(i < bufsize && (c = (which)?sockgetcharsrv(param, to, 0):sockgetcharcli(param, to, 0)) != EOF);
return i;
}
syntax highlighted by Code2HTML, v. 0.9.1