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 *)¶m->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 *)¶m->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 *)¶m->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 *)¶m->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