3proxy/src/sockgetchar.c

167 lines
4.8 KiB
C
Raw Normal View History

2014-04-08 17:03:21 +08:00
/*
3APA3A simpliest proxy server
2021-07-02 16:50:33 +08:00
(c) 2002-2021 by Vladimir Dubrovin <3proxy@3proxy.org>
2014-04-08 17:03:21 +08:00
please read License Agreement
*/
#include "proxy.h"
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(conf.timetoexit) return 0;
res = so._poll(&fds, 1, to*1000);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
2016-02-16 20:29:51 +08:00
res = so._send(sock, (char *)buf + sent, bufsize - sent, 0);
2014-04-08 17:03:21 +08:00
if(res < 0) {
if(errno == EAGAIN || errno == EINTR) continue;
break;
}
sent += res;
} while (sent < bufsize);
return sent;
}
int socksendto(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
2014-04-08 17:03:21 +08:00
int sent = 0;
int res;
struct pollfd fds;
fds.fd = sock;
do {
if(conf.timetoexit) return 0;
fds.events = POLLOUT;
res = so._poll(&fds, 1, to);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
2016-02-16 20:29:51 +08:00
res = so._sendto(sock, (char *)buf + sent, bufsize - sent, 0, sin, SASIZE(sin));
2014-04-08 17:03:21 +08:00
if(res < 0) {
2014-06-11 05:54:25 +08:00
if(errno != EAGAIN && errno != EINTR) break;
2014-04-08 17:03:21 +08:00
continue;
}
sent += res;
} while (sent < bufsize);
return sent;
}
int sockrecvfrom(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
2014-04-08 17:03:21 +08:00
struct pollfd fds;
SASIZETYPE sasize;
int res;
fds.fd = sock;
fds.events = POLLIN;
if(conf.timetoexit) return EOF;
if (so._poll(&fds, 1, to)<1) return 0;
sasize = SASIZE(sin);
2014-04-08 17:03:21 +08:00
do {
2016-02-16 20:29:51 +08:00
res = so._recvfrom(sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
2014-04-08 17:03:21 +08:00
} 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(SRVBUFSIZE))) return 0;
param->clibufsize = SRVBUFSIZE;
2014-04-08 17:03:21 +08:00
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, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
2014-04-08 17:03:21 +08:00
param->cliinbuf = len;
param->clioffset = 1;
return (int)*param->clibuf;
}
int sockfillbuffcli(struct clientparam * param, unsigned long size, int timeosec){
int len;
if(!param->clibuf) return 0;
if(param->cliinbuf == param->clioffset){
param->cliinbuf = param->clioffset = 0;
}
else if(param->clioffset){
memmove(param->clibuf, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset);
param->cliinbuf -= param->clioffset;
param->clioffset = 0;
}
if(size <= param->cliinbuf) return size;
size -= param->cliinbuf;
if((len = sockrecvfrom(param->clisock, (struct sockaddr *)&param->sincr, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){
2014-04-08 17:03:21 +08:00
param->cliinbuf += len;
}
return param->cliinbuf;
}
int sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec){
int len;
if(!param->srvbuf) return 0;
if(param->srvinbuf == param->srvoffset){
param->srvinbuf = param->srvoffset = 0;
}
else if(param->srvoffset){
memmove(param->srvbuf, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset);
param->srvinbuf -= param->srvoffset;
param->srvoffset = 0;
}
if(size <= param->srvinbuf) return size;
size -= param->srvinbuf;
if((len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sinsr, param->srvbuf + param->srvinbuf, (param->srvbufsize - param->srvinbuf) < size? param->srvbufsize - param->srvinbuf:size, timeosec*1000)) > 0){
2014-04-08 17:03:21 +08:00
param->srvinbuf += len;
param->nreads++;
param->statssrv64 += len;
2014-04-08 17:03:21 +08:00
}
return param->srvinbuf;
}
int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){
int len;
int bufsize;
if(!param->srvbuf){
bufsize = SRVBUFSIZE;
2014-04-08 17:03:21 +08:00
if(param->ndatfilterssrv > 0 && bufsize < 32768) bufsize = 32768;
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, (struct sockaddr *)&param->sinsr, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
2014-04-08 17:03:21 +08:00
param->srvinbuf = len;
param->srvoffset = 1;
param->nreads++;
param->statssrv64 += len;
2014-04-08 17:03:21 +08:00
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;
2018-04-28 00:23:20 +08:00
while(i < bufsize && (c = (which)?sockgetcharsrv(param, to, 0):sockgetcharcli(param, to, 0)) != EOF){
2014-04-08 17:03:21 +08:00
buf[i++] = c;
if(delim != EOF && c == delim) break;
2018-04-28 00:23:20 +08:00
}
2014-04-08 17:03:21 +08:00
return i;
}