1 /*
2    3APA3A simpliest proxy server
3    (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
4 
5    please read License Agreement
6 */
7 
8 #include "proxy.h"
9 
socksend(SOCKET sock,unsigned char * buf,int bufsize,int to)10 int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to){
11  int sent = 0;
12  int res;
13  struct pollfd fds;
14 
15  fds.fd = sock;
16  fds.events = POLLOUT;
17  do {
18 	if(conf.timetoexit) return 0;
19 	res = so._poll(&fds, 1, to*1000);
20 	if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
21 	if(res < 1) break;
22 	res = so._send(sock, (char *)buf + sent, bufsize - sent, 0);
23 	if(res < 0) {
24 		if(errno == EAGAIN || errno == EINTR) continue;
25 		break;
26 	}
27 	sent += res;
28  } while (sent < bufsize);
29  return sent;
30 }
31 
32 
socksendto(SOCKET sock,struct sockaddr * sin,unsigned char * buf,int bufsize,int to)33 int socksendto(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
34  int sent = 0;
35  int res;
36  struct pollfd fds;
37 
38  fds.fd = sock;
39  do {
40 	if(conf.timetoexit) return 0;
41 	fds.events = POLLOUT;
42  	res = so._poll(&fds, 1, to);
43 	if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
44 	if(res < 1) break;
45 	res = so._sendto(sock, (char *)buf + sent, bufsize - sent, 0, sin, SASIZE(sin));
46 	if(res < 0) {
47 		if(errno !=  EAGAIN && errno != EINTR) break;
48 		continue;
49 	}
50 	sent += res;
51  } while (sent < bufsize);
52  return sent;
53 }
54 
sockrecvfrom(SOCKET sock,struct sockaddr * sin,unsigned char * buf,int bufsize,int to)55 int sockrecvfrom(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
56 	struct pollfd fds;
57 	SASIZETYPE sasize;
58 	int res;
59 
60 	fds.fd = sock;
61 	fds.events = POLLIN;
62 	if(conf.timetoexit) return EOF;
63 	if (so._poll(&fds, 1, to)<1) return 0;
64 	sasize = SASIZE(sin);
65 	do {
66 		res = so._recvfrom(sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
67 	} while (res < 0 && (errno == EAGAIN || errno == EINTR));
68 	return res;
69 }
70 
sockgetcharcli(struct clientparam * param,int timeosec,int timeousec)71 int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){
72 	int len;
73 
74 	if(!param->clibuf){
75 		if(!(param->clibuf = myalloc(SRVBUFSIZE))) return 0;
76 		param->clibufsize = SRVBUFSIZE;
77 		param->clioffset = param->cliinbuf = 0;
78 	}
79 	if(param->cliinbuf && param->clioffset < param->cliinbuf){
80 		return (int)param->clibuf[param->clioffset++];
81 	}
82 	param->clioffset = param->cliinbuf = 0;
83 	if ((len = sockrecvfrom(param->clisock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
84 	param->cliinbuf = len;
85 	param->clioffset = 1;
86 	return (int)*param->clibuf;
87 }
88 
sockfillbuffcli(struct clientparam * param,unsigned long size,int timeosec)89 int sockfillbuffcli(struct clientparam * param, unsigned long size, int timeosec){
90 	int len;
91 
92 	if(!param->clibuf) return 0;
93 	if(param->cliinbuf == param->clioffset){
94 		param->cliinbuf = param->clioffset = 0;
95 	}
96 	else if(param->clioffset){
97 		memmove(param->clibuf, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset);
98 		param->cliinbuf -= param->clioffset;
99 		param->clioffset = 0;
100 	}
101 	if(size <= param->cliinbuf) return size;
102 	size -= param->cliinbuf;
103 	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){
104 		param->cliinbuf += len;
105 	}
106 	return param->cliinbuf;
107 }
108 
sockfillbuffsrv(struct clientparam * param,unsigned long size,int timeosec)109 int sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec){
110 	int len;
111 
112 	if(!param->srvbuf) return 0;
113 	if(param->srvinbuf == param->srvoffset){
114 		param->srvinbuf = param->srvoffset = 0;
115 	}
116 	else if(param->srvoffset){
117 		memmove(param->srvbuf, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset);
118 		param->srvinbuf -= param->srvoffset;
119 		param->srvoffset = 0;
120 	}
121 	if(size <= param->srvinbuf) return size;
122 	size -= param->srvinbuf;
123 	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){
124 		param->srvinbuf += len;
125 		param->nreads++;
126 		param->statssrv64 += len;
127 	}
128 	return param->srvinbuf;
129 }
130 
131 
sockgetcharsrv(struct clientparam * param,int timeosec,int timeousec)132 int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){
133 	int len;
134 	int bufsize;
135 
136 	if(!param->srvbuf){
137 		bufsize = SRVBUFSIZE;
138 		if(param->ndatfilterssrv > 0 && bufsize < 32768) bufsize = 32768;
139 		if(!(param->srvbuf = myalloc(bufsize))) return 0;
140 		param->srvbufsize = bufsize;
141 		param->srvoffset = param->srvinbuf = 0;
142 
143 	}
144 	if(param->srvinbuf && param->srvoffset < param->srvinbuf){
145 		return (int)param->srvbuf[param->srvoffset++];
146 	}
147 	param->srvoffset = param->srvinbuf = 0;
148 	if ((len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sinsr, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
149 	param->srvinbuf = len;
150 	param->srvoffset = 1;
151 	param->nreads++;
152 	param->statssrv64 += len;
153 	return (int)*param->srvbuf;
154 }
155 
sockgetlinebuf(struct clientparam * param,DIRECTION which,unsigned char * buf,int bufsize,int delim,int to)156 int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to){
157  int c;
158  int i=0;
159 
160  while(i < bufsize && (c = (which)?sockgetcharsrv(param, to, 0):sockgetcharcli(param, to, 0)) != EOF){
161 	buf[i++] = c;
162 	if(delim != EOF && c == delim) break;
163  }
164  return i;
165 }
166 
167