proxymain.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2017 by Vladimir Dubrovin <3proxy@3proxy.ru>
  4. please read License Agreement
  5. */
  6. #include "proxy.h"
  7. #define param ((struct clientparam *) p)
  8. #ifdef _WIN32
  9. DWORD WINAPI threadfunc(LPVOID p) {
  10. #else
  11. void * threadfunc (void *p) {
  12. #endif
  13. int i = -1;
  14. if(param->srv->cbsock != INVALID_SOCKET){
  15. SASIZETYPE size = sizeof(param->sinsr);
  16. struct pollfd fds;
  17. fds.fd = param->srv->cbsock;
  18. fds.events = POLLIN;
  19. fds.revents = 0;
  20. for(i=5+(param->srv->maxchild>>10); i; i--){
  21. if(so._poll(&fds, 1, 1000*CONNBACK_TO)!=1){
  22. dolog(param, (unsigned char *)"Connect back not received, check connback client");
  23. i = 0;
  24. break;
  25. }
  26. param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)&param->sinsr, &size);
  27. if(param->remsock == INVALID_SOCKET) {
  28. dolog(param, (unsigned char *)"Connect back accept() failed");
  29. continue;
  30. }
  31. #ifndef WITHMAIN
  32. param->req = param->sinsr;
  33. if(param->srv->acl) param->res = checkACL(param);
  34. if(param->res){
  35. dolog(param, (unsigned char *)"Connect back ACL failed");
  36. so._closesocket(param->remsock);
  37. param->remsock = INVALID_SOCKET;
  38. continue;
  39. }
  40. #endif
  41. if(socksendto(param->remsock, (struct sockaddr*)&param->sinsr, (unsigned char *)"C", 1, CONNBACK_TO) != 1){
  42. dolog(param, (unsigned char *)"Connect back sending command failed");
  43. so._closesocket(param->remsock);
  44. param->remsock = INVALID_SOCKET;
  45. continue;
  46. }
  47. break;
  48. }
  49. }
  50. if(!i){
  51. param->res = 13;
  52. freeparam(param);
  53. }
  54. else {
  55. #ifndef _WIN32
  56. sigset_t mask;
  57. sigfillset(&mask);
  58. pthread_sigmask(SIG_SETMASK, &mask, NULL);
  59. #endif
  60. ((struct clientparam *) p)->srv->pf((struct clientparam *)p);
  61. }
  62. #ifdef _WIN32
  63. return 0;
  64. #else
  65. return NULL;
  66. #endif
  67. }
  68. #undef param
  69. struct socketoptions sockopts[] = {
  70. #ifdef TCP_NODELAY
  71. {TCP_NODELAY, "TCP_NODELAY"},
  72. #endif
  73. #ifdef TCP_CORK
  74. {TCP_CORK, "TCP_CORK"},
  75. #endif
  76. #ifdef TCP_DEFER_ACCEPT
  77. {TCP_DEFER_ACCEPT, "TCP_DEFER_ACCEPT"},
  78. #endif
  79. #ifdef TCP_QUICKACK
  80. {TCP_QUICKACK, "TCP_QUICKACK"},
  81. #endif
  82. #ifdef TCP_TIMESTAMPS
  83. {TCP_TIMESTAMPS, "TCP_TIMESTAMPS"},
  84. #endif
  85. #ifdef USE_TCP_FASTOPEN
  86. {USE_TCP_FASTOPEN, "USE_TCP_FASTOPEN"},
  87. #endif
  88. #ifdef SO_REUSEADDR
  89. {SO_REUSEADDR, "SO_REUSEADDR"},
  90. #endif
  91. #ifdef SO_REUSEPORT
  92. {SO_REUSEPORT, "SO_REUSEPORT"},
  93. #endif
  94. #ifdef SO_PORT_SCALABILITY
  95. {SO_PORT_SCALABILITY, "SO_PORT_SCALABILITY"},
  96. #endif
  97. #ifdef SO_REUSE_UNICASTPORT
  98. {SO_REUSE_UNICASTPORT, "SO_REUSE_UNICASTPORT"},
  99. #endif
  100. #ifdef SO_KEEPALIVE
  101. {SO_KEEPALIVE, "SO_KEEPALIVE"},
  102. #endif
  103. #ifdef SO_DONTROUTE
  104. {SO_DONTROUTE, "SO_DONTROUTE"},
  105. #endif
  106. #ifdef IP_TRANSPARENT
  107. {IP_TRANSPARENT, "IP_TRANSPARENT"},
  108. #endif
  109. {0, NULL}
  110. };
  111. char optsbuf[1024];
  112. char * printopts(char *sep){
  113. int i=0, pos=0;
  114. for(; sockopts[i].optname; i++)pos += sprintf(optsbuf+pos,"%s%s",i?sep:"",sockopts[i].optname);
  115. return optsbuf;
  116. }
  117. int getopts(const char *s){
  118. int i=0, ret=0;
  119. for(; sockopts[i].optname; i++)if(strstr(s,sockopts[i].optname)) ret |= (1<<i);
  120. return ret;
  121. }
  122. void setopts(SOCKET s, int opts){
  123. int i, opt, set;
  124. for(i = 0; opts >= (opt = (1<<i)); i++){
  125. set = 1;
  126. if(opts & opt) setsockopt(s, *sockopts[i].optname == 'T'? IPPROTO_TCP:
  127. #ifdef SOL_IP
  128. *sockopts[i].optname == 'I'? SOL_IP:
  129. #endif
  130. SOL_SOCKET, sockopts[i].opt, (char *)&set, sizeof(set));
  131. }
  132. }
  133. #ifndef MODULEMAINFUNC
  134. #define MODULEMAINFUNC main
  135. #define STDMAIN
  136. #ifndef _WINCE
  137. int main (int argc, char** argv){
  138. #else
  139. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow){
  140. int argc;
  141. char ** argv;
  142. WNDCLASS wc;
  143. HWND hwnd = 0;
  144. #endif
  145. #else
  146. extern int linenum;
  147. extern int haveerror;
  148. int MODULEMAINFUNC (int argc, char** argv){
  149. #endif
  150. SOCKET sock = INVALID_SOCKET, new_sock = INVALID_SOCKET;
  151. int i=0;
  152. SASIZETYPE size;
  153. pthread_t thread;
  154. struct clientparam defparam;
  155. struct srvparam srv;
  156. struct clientparam * newparam;
  157. int error = 0;
  158. unsigned sleeptime;
  159. unsigned char buf[256];
  160. char *hostname=NULL;
  161. int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
  162. unsigned char *cbc_string = NULL, *cbl_string = NULL;
  163. #ifndef NOIPV6
  164. struct sockaddr_in6 cbsa;
  165. #else
  166. struct sockaddr_in cbsa;
  167. #endif
  168. FILE *fp = NULL;
  169. struct linger lg;
  170. int nlog = 5000;
  171. char loghelp[] =
  172. #ifdef STDMAIN
  173. #ifndef _WIN32
  174. " -I inetd mode (requires real socket, doesn't work with TTY)\n"
  175. " -l@IDENT log to syslog IDENT\n"
  176. #endif
  177. " -d go to background (daemon)\n"
  178. #else
  179. " -u never ask for username\n"
  180. " -u2 always ask for username\n"
  181. #endif
  182. #ifdef SO_BINDTODEVICE
  183. " -Di(DEVICENAME) bind internal interface to device, e.g. eth1\n"
  184. " -De(DEVICENAME) bind external interface to device, e.g. eth1\n"
  185. #endif
  186. #ifdef WITHSLICE
  187. " -s Use slice() - faster proxing, but no filtering for data\n"
  188. #endif
  189. " -fFORMAT logging format (see documentation)\n"
  190. " -l log to stderr\n"
  191. " -lFILENAME log to FILENAME\n"
  192. " -b(BUFSIZE) size of network buffer (default 4096 for TCP, 16384 for UDP)\n"
  193. " -S(STACKSIZE) value to add to default client thread stack size\n"
  194. " -t be silent (do not log service start/stop)\n"
  195. "\n"
  196. " -iIP ip address or internal interface (clients are expected to connect)\n"
  197. " -eIP ip address or external interface (outgoing connection will have this)\n"
  198. " -rHOST:PORT Use IP:port for connect back proxy instead of listen port\n"
  199. " -RHOST:PORT Use PORT to listen connect back proxy connection to pass data to\n"
  200. " -4 Use IPv4 for outgoing connections\n"
  201. " -6 Use IPv6 for outgoing connections\n"
  202. " -46 Prefer IPv4 for outgoing connections, use both IPv4 and IPv6\n"
  203. " -64 Prefer IPv6 for outgoing connections, use both IPv4 and IPv6\n"
  204. " -ocOPTIONS, -osOPTIONS, -olOPTIONS, -orOPTIONS -oROPTIONS - options for\n"
  205. " to-client (oc), to-server (os), listening (ol) socket, connect back client\n"
  206. " (or) socket, connect back server (oR) listening socket\n"
  207. " where possible options are: ";
  208. #ifdef _WIN32
  209. unsigned long ul = 1;
  210. #else
  211. pthread_attr_t pa;
  212. #ifdef STDMAIN
  213. int inetd = 0;
  214. #endif
  215. #endif
  216. #ifdef _WIN32
  217. HANDLE h;
  218. #endif
  219. #ifdef STDMAIN
  220. #ifdef _WINCE
  221. argc = ceparseargs((char *)lpCmdLine);
  222. argv = ceargv;
  223. if(FindWindow(lpCmdLine, lpCmdLine)) return 0;
  224. ZeroMemory(&wc,sizeof(wc));
  225. wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  226. wc.hInstance=hInstance;
  227. wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  228. wc.lpfnWndProc=DefWindowProc;
  229. wc.style=CS_HREDRAW|CS_VREDRAW;
  230. wc.lpszClassName=lpCmdLine;
  231. RegisterClass(&wc);
  232. hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,lpCmdLine,lpCmdLine,WS_VISIBLE|WS_POPUP,0,0,0,0,0,0,hInstance,0);
  233. #endif
  234. #ifdef _WIN32
  235. WSADATA wd;
  236. WSAStartup(MAKEWORD( 1, 1 ), &wd);
  237. #endif
  238. #endif
  239. srvinit(&srv, &defparam);
  240. srv.pf = childdef.pf;
  241. isudp = childdef.isudp;
  242. srv.service = defparam.service = childdef.service;
  243. #ifndef STDMAIN
  244. srv.acl = copyacl(conf.acl);
  245. srv.authfuncs = copyauth(conf.authfuncs);
  246. if(!conf.services){
  247. conf.services = &srv;
  248. }
  249. else {
  250. srv.next = conf.services;
  251. conf.services = conf.services->prev = &srv;
  252. }
  253. #else
  254. srv.needuser = 0;
  255. initlog();
  256. #endif
  257. #ifndef _WIN32
  258. {
  259. sigset_t mask;
  260. sigfillset(&mask);
  261. pthread_sigmask(SIG_SETMASK, &mask, NULL);
  262. }
  263. #endif
  264. for (i=1; i<argc; i++) {
  265. if(*argv[i]=='-') {
  266. switch(argv[i][1]) {
  267. case 'd':
  268. if(!conf.demon)daemonize();
  269. conf.demon = 1;
  270. break;
  271. #ifdef SO_BINDTODEVICE
  272. case 'D':
  273. if(argv[i][2] == 'i') srv.ibindtodevice = mystrdup(argv[i] + 3);
  274. else srv.obindtodevice = mystrdup(argv[i] + 3);
  275. break;
  276. #endif
  277. case 'l':
  278. if(srv.logtarget) myfree(srv.logtarget);
  279. srv.logtarget = (unsigned char *)mystrdup(argv[i] + 2);
  280. if(argv[i][2]) {
  281. if(argv[i][2]=='@'){
  282. #ifdef STDMAIN
  283. #ifndef _WIN32
  284. openlog(argv[i]+3, LOG_PID, LOG_DAEMON);
  285. srv.logfunc = logsyslog;
  286. #endif
  287. #endif
  288. }
  289. else {
  290. fp = fopen(argv[i] + 2, "a");
  291. if (fp) {
  292. srv.stdlog = fp;
  293. fseek(fp, 0L, SEEK_END);
  294. }
  295. }
  296. }
  297. break;
  298. case 'i':
  299. getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.intsa);
  300. break;
  301. case 'e':
  302. {
  303. #ifndef NOIPV6
  304. struct sockaddr_in6 sa6;
  305. memset(&sa6, 0, sizeof(sa6));
  306. error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6);
  307. if(!error) {
  308. if (*SAFAMILY(&sa6)==AF_INET) srv.extsa = sa6;
  309. else srv.extsa6 = sa6;
  310. }
  311. #else
  312. error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extsa);
  313. #endif
  314. }
  315. break;
  316. case 'N':
  317. getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
  318. break;
  319. case 'p':
  320. *SAPORT(&srv.intsa) = htons(atoi(argv[i]+2));
  321. break;
  322. case '4':
  323. case '6':
  324. srv.family = atoi(argv[i]+1);
  325. break;
  326. case 'b':
  327. srv.bufsize = atoi(argv[i]+2);
  328. break;
  329. case 'n':
  330. srv.usentlm = atoi(argv[i]+2);
  331. break;
  332. #ifdef STDMAIN
  333. #ifndef _WIN32
  334. case 'I':
  335. size = sizeof(defparam.sincl);
  336. if(so._getsockname(0, (struct sockaddr*)&defparam.sincl, &size) ||
  337. *SAFAMILY(&defparam.sincl) != AF_INET) error = 1;
  338. else inetd = 1;
  339. break;
  340. #endif
  341. #endif
  342. case 'f':
  343. if(srv.logformat)myfree(srv.logformat);
  344. srv.logformat = (unsigned char *)mystrdup(argv[i] + 2);
  345. break;
  346. case 't':
  347. srv.silent = 1;
  348. break;
  349. case 'h':
  350. hostname = argv[i] + 2;
  351. break;
  352. case 'r':
  353. cbc_string = (unsigned char *)mystrdup(argv[i] + 2);
  354. iscbc = 1;
  355. break;
  356. case 'R':
  357. cbl_string = (unsigned char *)mystrdup(argv[i] + 2);
  358. iscbl = 1;
  359. break;
  360. case 'u':
  361. srv.needuser = 0;
  362. if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2);
  363. break;
  364. case 'T':
  365. srv.transparent = 1;
  366. break;
  367. case 'S':
  368. srv.stacksize = atoi(argv[i]+2);
  369. break;
  370. case 'a':
  371. srv.anonymous = 1 + atoi(argv[i]+2);
  372. break;
  373. case 's':
  374. #ifdef WITHSPLICE
  375. if(isudp || srv.service == S_ADMIN)
  376. #endif
  377. srv.singlepacket = 1 + atoi(argv[i]+2);
  378. #ifdef WITHSPLICE
  379. else
  380. if(*(argv[i]+2)) srv.usesplice = atoi(argv[i]+2);
  381. #endif
  382. break;
  383. case 'o':
  384. switch(argv[i][2]){
  385. case 's':
  386. srv.srvsockopts = getopts(argv[i]+3);
  387. break;
  388. case 'c':
  389. srv.clisockopts = getopts(argv[i]+3);
  390. break;
  391. case 'l':
  392. srv.lissockopts = getopts(argv[i]+3);
  393. break;
  394. case 'r':
  395. srv.cbcsockopts = getopts(argv[i]+3);
  396. break;
  397. case 'R':
  398. srv.cbcsockopts = getopts(argv[i]+3);
  399. break;
  400. default:
  401. error = 1;
  402. }
  403. if(!error) break;
  404. default:
  405. error = 1;
  406. break;
  407. }
  408. }
  409. else break;
  410. }
  411. #ifndef STDMAIN
  412. if(childdef.port) {
  413. #endif
  414. #ifndef PORTMAP
  415. if (error || i!=argc) {
  416. #ifndef STDMAIN
  417. haveerror = 1;
  418. conf.threadinit = 0;
  419. #endif
  420. fprintf(stderr, "%s of %s\n"
  421. "Usage: %s options\n"
  422. "Available options are:\n"
  423. "%s\n"
  424. "\t%s\n"
  425. " -pPORT - service port to accept connections\n"
  426. "%s"
  427. "\tExample: %s -i127.0.0.1\n\n"
  428. "%s",
  429. argv[0],
  430. conf.stringtable?(char *)conf.stringtable[3]: VERSION " (" BUILDDATE ")",
  431. argv[0], loghelp, printopts("\n\t"), childdef.helpmessage, argv[0],
  432. #ifdef STDMAIN
  433. copyright
  434. #else
  435. ""
  436. #endif
  437. );
  438. return (1);
  439. }
  440. #endif
  441. #ifndef STDMAIN
  442. }
  443. else {
  444. #endif
  445. #ifndef NOPORTMAP
  446. if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
  447. #ifndef STDMAIN
  448. haveerror = 1;
  449. conf.threadinit = 0;
  450. #endif
  451. fprintf(stderr, "%s of %s\n"
  452. "Usage: %s options"
  453. " [-e<external_ip>] <port_to_bind>"
  454. " <target_hostname> <target_port>\n"
  455. "Available options are:\n"
  456. "%s\n"
  457. "\t%s\n"
  458. "%s"
  459. "\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
  460. "%s",
  461. argv[0],
  462. conf.stringtable?(char *)conf.stringtable[3]: VERSION " (" BUILDDATE ")",
  463. argv[0], loghelp, printopts("\n\t"), childdef.helpmessage, argv[0],
  464. #ifdef STDMAIN
  465. copyright
  466. #else
  467. ""
  468. #endif
  469. );
  470. return (1);
  471. }
  472. srv.target = (unsigned char *)mystrdup(argv[i+1]);
  473. #endif
  474. #ifndef STDMAIN
  475. }
  476. #else
  477. #ifndef _WIN32
  478. if(inetd) {
  479. fcntl(0,F_SETFL,O_NONBLOCK | fcntl(0,F_GETFL));
  480. if(!isudp){
  481. so._setsockopt(0, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
  482. so._setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));
  483. }
  484. defparam.clisock = 0;
  485. if(! (newparam = myalloc (sizeof(defparam)))){
  486. return 2;
  487. };
  488. *newparam = defparam;
  489. return((*srv.pf)((void *)newparam)? 1:0);
  490. }
  491. #endif
  492. #endif
  493. srvinit2(&srv, &defparam);
  494. if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET;
  495. if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port);
  496. *SAFAMILY(&srv.extsa) = AF_INET;
  497. #ifndef NOIPV6
  498. *SAFAMILY(&srv.extsa6) = AF_INET6;
  499. #endif
  500. if(hostname)parsehostname(hostname, &defparam, childdef.port);
  501. #ifndef STDMAIN
  502. copyfilter(conf.filters, &srv);
  503. conf.threadinit = 0;
  504. #endif
  505. if (!iscbc) {
  506. if(srv.srvsock == INVALID_SOCKET){
  507. if(!isudp){
  508. lg.l_onoff = 1;
  509. lg.l_linger = conf.timeouts[STRING_L];
  510. sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
  511. }
  512. else {
  513. sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
  514. }
  515. if( sock == INVALID_SOCKET) {
  516. perror("socket()");
  517. return -2;
  518. }
  519. setopts(sock, srv.lissockopts);
  520. #ifdef _WIN32
  521. ioctlsocket(sock, FIONBIO, &ul);
  522. #else
  523. fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL));
  524. #endif
  525. srv.srvsock = sock;
  526. opt = 1;
  527. if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()");
  528. #ifdef SO_REUSEPORT
  529. opt = 1;
  530. so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
  531. #endif
  532. #ifdef SO_BINDTODEVICE
  533. if(srv.ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1);
  534. #endif
  535. }
  536. size = sizeof(srv.intsa);
  537. for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, SASIZE(&srv.intsa))==-1; usleep(sleeptime)) {
  538. sprintf((char *)buf, "bind(): %s", strerror(errno));
  539. if(!srv.silent)dolog(&defparam, buf);
  540. sleeptime = (sleeptime<<1);
  541. if(!sleeptime) {
  542. so._closesocket(sock);
  543. return -3;
  544. }
  545. }
  546. if(!isudp){
  547. if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) {
  548. sprintf((char *)buf, "listen(): %s", strerror(errno));
  549. if(!srv.silent)dolog(&defparam, buf);
  550. return -4;
  551. }
  552. }
  553. else
  554. defparam.clisock = sock;
  555. if(!srv.silent && !iscbc){
  556. sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
  557. dolog(&defparam, buf);
  558. }
  559. }
  560. if(iscbl){
  561. parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
  562. if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
  563. dolog(&defparam, (unsigned char *)"Failed to allocate connect back socket");
  564. return -6;
  565. }
  566. opt = 1;
  567. so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
  568. #ifdef SO_REUSEPORT
  569. opt = 1;
  570. so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
  571. #endif
  572. setopts(srv.cbsock, srv.cbssockopts);
  573. if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
  574. dolog(&defparam, (unsigned char *)"Failed to bind connect back socket");
  575. return -7;
  576. }
  577. if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
  578. dolog(&defparam, (unsigned char *)"Failed to listen connect back socket");
  579. return -8;
  580. }
  581. }
  582. srv.fds.fd = sock;
  583. srv.fds.events = POLLIN;
  584. #ifndef _WIN32
  585. pthread_attr_init(&pa);
  586. pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv.stacksize));
  587. pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
  588. #endif
  589. for (;;) {
  590. for(;;){
  591. while((conf.paused == srv.paused && srv.childcount >= srv.maxchild)){
  592. nlog++;
  593. if(!srv.silent && nlog > 5000) {
  594. sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv.childcount, srv.maxchild);
  595. dolog(&defparam, buf);
  596. nlog = 0;
  597. }
  598. usleep(SLEEPTIME);
  599. }
  600. if (iscbc) break;
  601. if (conf.paused != srv.paused) break;
  602. if (srv.fds.events & POLLIN) {
  603. error = so._poll(&srv.fds, 1, 1000);
  604. }
  605. else {
  606. usleep(SLEEPTIME);
  607. continue;
  608. }
  609. if (error >= 1) break;
  610. if (error == 0) continue;
  611. if (errno != EAGAIN && errno != EINTR) {
  612. sprintf((char *)buf, "poll(): %s/%d", strerror(errno), errno);
  613. if(!srv.silent)dolog(&defparam, buf);
  614. break;
  615. }
  616. }
  617. if((conf.paused != srv.paused) || (error < 0)) break;
  618. error = 0;
  619. if(!isudp){
  620. size = sizeof(defparam.sincr);
  621. if(iscbc){
  622. new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
  623. if(new_sock != INVALID_SOCKET){
  624. setopts(new_sock, srv.cbcsockopts);
  625. parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
  626. if(connectwithpoll(new_sock,(struct sockaddr *)&defparam.sincr,SASIZE(&defparam.sincr),CONNBACK_TO)) {
  627. so._closesocket(new_sock);
  628. new_sock = INVALID_SOCKET;
  629. usleep(SLEEPTIME);
  630. continue;
  631. }
  632. if(sockrecvfrom(new_sock,(struct sockaddr*)&defparam.sincr,buf,1,60) != 1 || *buf!='C') {
  633. so._closesocket(new_sock);
  634. new_sock = INVALID_SOCKET;
  635. usleep(SLEEPTIME);
  636. continue;
  637. }
  638. }
  639. else {
  640. usleep(SLEEPTIME);
  641. continue;
  642. }
  643. }
  644. else {
  645. new_sock = so._accept(sock, (struct sockaddr*)&defparam.sincr, &size);
  646. if(new_sock == INVALID_SOCKET){
  647. #ifdef _WIN32
  648. switch(WSAGetLastError()){
  649. case WSAEMFILE:
  650. case WSAENOBUFS:
  651. case WSAENETDOWN:
  652. usleep(SLEEPTIME * 10);
  653. break;
  654. case WSAEINTR:
  655. error = 1;
  656. break;
  657. default:
  658. break;
  659. }
  660. #else
  661. switch (errno){
  662. #ifdef EMFILE
  663. case EMFILE:
  664. #endif
  665. #ifdef ENFILE
  666. case ENFILE:
  667. #endif
  668. #ifdef ENOBUFS
  669. case ENOBUFS:
  670. #endif
  671. #ifdef ENOMEM
  672. case ENOMEM:
  673. #endif
  674. usleep(SLEEPTIME * 10);
  675. break;
  676. default:
  677. break;
  678. }
  679. #endif
  680. nlog++;
  681. if(!srv.silent && (error || nlog > 5000)) {
  682. sprintf((char *)buf, "accept(): %s", strerror(errno));
  683. dolog(&defparam, buf);
  684. nlog = 0;
  685. }
  686. continue;
  687. }
  688. }
  689. setopts(new_sock, srv.clisockopts);
  690. size = sizeof(defparam.sincl);
  691. if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
  692. sprintf((char *)buf, "getsockname(): %s", strerror(errno));
  693. if(!srv.silent)dolog(&defparam, buf);
  694. continue;
  695. }
  696. #ifdef _WIN32
  697. ioctlsocket(new_sock, FIONBIO, &ul);
  698. #else
  699. fcntl(new_sock,F_SETFL,O_NONBLOCK | fcntl(new_sock,F_GETFL));
  700. #endif
  701. so._setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
  702. so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
  703. }
  704. else {
  705. srv.fds.events = 0;
  706. }
  707. if(! (newparam = myalloc (sizeof(defparam)))){
  708. if(!isudp) so._closesocket(new_sock);
  709. defparam.res = 21;
  710. if(!srv.silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed");
  711. usleep(SLEEPTIME);
  712. continue;
  713. };
  714. *newparam = defparam;
  715. if(defparam.hostname)newparam->hostname=(unsigned char *)mystrdup((char *)defparam.hostname);
  716. clearstat(newparam);
  717. if(!isudp) newparam->clisock = new_sock;
  718. #ifndef STDMAIN
  719. if(makefilters(&srv, newparam) > CONTINUE){
  720. freeparam(newparam);
  721. continue;
  722. }
  723. #endif
  724. newparam->prev = newparam->next = NULL;
  725. error = 0;
  726. pthread_mutex_lock(&srv.counter_mutex);
  727. if(!srv.child){
  728. srv.child = newparam;
  729. }
  730. else {
  731. newparam->next = srv.child;
  732. srv.child = srv.child->prev = newparam;
  733. }
  734. #ifdef _WIN32
  735. #ifndef _WINCE
  736. h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
  737. #else
  738. h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
  739. #endif
  740. srv.childcount++;
  741. if (h) {
  742. newparam->threadid = (unsigned)thread;
  743. CloseHandle(h);
  744. }
  745. else {
  746. sprintf((char *)buf, "_beginthreadex(): %s", _strerror(NULL));
  747. if(!srv.silent)dolog(&defparam, buf);
  748. error = 1;
  749. }
  750. #else
  751. error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
  752. srv.childcount++;
  753. if(error){
  754. sprintf((char *)buf, "pthread_create(): %s", strerror(error));
  755. if(!srv.silent)dolog(&defparam, buf);
  756. }
  757. else {
  758. newparam->threadid = (unsigned)thread;
  759. }
  760. #endif
  761. pthread_mutex_unlock(&srv.counter_mutex);
  762. if(error) freeparam(newparam);
  763. memset(&defparam.sincl, 0, sizeof(defparam.sincl));
  764. memset(&defparam.sincr, 0, sizeof(defparam.sincr));
  765. if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
  766. }
  767. if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
  768. srvfree(&srv);
  769. #ifndef STDMAIN
  770. pthread_mutex_lock(&config_mutex);
  771. if(srv.next)srv.next->prev = srv.prev;
  772. if(srv.prev)srv.prev->next = srv.next;
  773. else conf.services = srv.next;
  774. pthread_mutex_unlock(&config_mutex);
  775. #endif
  776. #ifndef _WIN32
  777. pthread_attr_destroy(&pa);
  778. #endif
  779. if(defparam.hostname)myfree(defparam.hostname);
  780. if(cbc_string)myfree(cbc_string);
  781. if(cbl_string)myfree(cbl_string);
  782. if(fp) fclose(fp);
  783. return 0;
  784. }
  785. void srvinit(struct srvparam * srv, struct clientparam *param){
  786. memset(srv, 0, sizeof(struct srvparam));
  787. srv->version = conf.version + 1;
  788. srv->paused = conf.paused;
  789. srv->logfunc = havelog?conf.logfunc:NULL;
  790. srv->noforce = conf.noforce;
  791. srv->logformat = conf.logformat? (unsigned char *)mystrdup((char *)conf.logformat) : NULL;
  792. srv->authfunc = conf.authfunc;
  793. srv->usentlm = 0;
  794. srv->maxchild = conf.maxchild;
  795. srv->stacksize = conf.stacksize;
  796. srv->time_start = time(NULL);
  797. if(havelog && conf.logtarget){
  798. srv->logtarget = (unsigned char *)mystrdup((char *)conf.logtarget);
  799. }
  800. srv->srvsock = INVALID_SOCKET;
  801. srv->logdumpsrv = conf.logdumpsrv;
  802. srv->logdumpcli = conf.logdumpcli;
  803. srv->cbsock = INVALID_SOCKET;
  804. srv->needuser = 1;
  805. #ifdef WITHSPLICE
  806. srv->usesplice = 1;
  807. #endif
  808. memset(param, 0, sizeof(struct clientparam));
  809. param->srv = srv;
  810. param->version = srv->version;
  811. param->paused = srv->paused;
  812. param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
  813. *SAFAMILY(&param->req) = *SAFAMILY(&param->sinsl) = *SAFAMILY(&param->sinsr) = *SAFAMILY(&param->sincr) = *SAFAMILY(&param->sincl) = AF_INET;
  814. pthread_mutex_init(&srv->counter_mutex, NULL);
  815. srv->intsa = conf.intsa;
  816. srv->extsa = conf.extsa;
  817. #ifndef NOIPV6
  818. srv->extsa6 = conf.extsa6;
  819. #endif
  820. }
  821. void srvinit2(struct srvparam * srv, struct clientparam *param){
  822. if(srv->logformat){
  823. char *s;
  824. if(*srv->logformat == '-' && (s = strchr((char *)srv->logformat + 1, '+')) && s[1]){
  825. unsigned char* logformat = srv->logformat;
  826. *s = 0;
  827. srv->nonprintable = (unsigned char *)mystrdup((char *)srv->logformat + 1);
  828. srv->replace = s[1];
  829. srv->logformat = (unsigned char *)mystrdup(s + 2);
  830. *s = '+';
  831. myfree(logformat);
  832. }
  833. }
  834. memset(&param->sinsl, 0, sizeof(param->sinsl));
  835. memset(&param->sinsr, 0, sizeof(param->sinsr));
  836. memset(&param->req, 0, sizeof(param->req));
  837. *SAFAMILY(&param->sinsl) = AF_INET;
  838. *SAFAMILY(&param->sinsr) = AF_INET;
  839. *SAFAMILY(&param->req) = AF_INET;
  840. param->sincr = param->sincl = srv->intsa;
  841. #ifndef NOIPV6
  842. if (srv->family == 6 || srv->family == 64) param->sinsr = srv->extsa6;
  843. else
  844. #endif
  845. param->sinsr = srv->extsa;
  846. }
  847. void srvfree(struct srvparam * srv){
  848. if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
  849. srv->srvsock = INVALID_SOCKET;
  850. if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
  851. srv->cbsock = INVALID_SOCKET;
  852. srv->service = S_ZOMBIE;
  853. while(srv->child) usleep(SLEEPTIME * 100);
  854. #ifndef STDMAIN
  855. if(srv->filter){
  856. while(srv->nfilters){
  857. srv->nfilters--;
  858. if(srv->filter[srv->nfilters].filter_close){
  859. (*srv->filter[srv->nfilters].filter_close)(srv->filter[srv->nfilters].data);
  860. }
  861. }
  862. myfree(srv->filter);
  863. }
  864. if(srv->acl)freeacl(srv->acl);
  865. if(srv->authfuncs)freeauth(srv->authfuncs);
  866. #endif
  867. pthread_mutex_destroy(&srv->counter_mutex);
  868. if(srv->target) myfree(srv->target);
  869. if(srv->logtarget) myfree(srv->logtarget);
  870. if(srv->logformat) myfree(srv->logformat);
  871. if(srv->nonprintable) myfree(srv->nonprintable);
  872. #ifdef SO_BINDTODEVICE
  873. if(srv->ibindtodevice) myfree(srv->ibindtodevice);
  874. if(srv->obindtodevice) myfree(srv->obindtodevice);
  875. #endif
  876. }
  877. void freeparam(struct clientparam * param) {
  878. if(param->res == 2) return;
  879. if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
  880. so._shutdown(param->ctrlsocksrv, SHUT_RDWR);
  881. so._closesocket(param->ctrlsocksrv);
  882. }
  883. if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
  884. so._shutdown(param->ctrlsock, SHUT_RDWR);
  885. so._closesocket(param->ctrlsock);
  886. }
  887. if(param->remsock != INVALID_SOCKET) {
  888. so._shutdown(param->remsock, SHUT_RDWR);
  889. so._closesocket(param->remsock);
  890. }
  891. if(param->clisock != INVALID_SOCKET) {
  892. so._shutdown(param->clisock, SHUT_RDWR);
  893. so._closesocket(param->clisock);
  894. }
  895. myfree(param->clibuf);
  896. myfree(param->srvbuf);
  897. if(param->datfilterssrv) myfree(param->datfilterssrv);
  898. #ifndef STDMAIN
  899. if(param->reqfilters) myfree(param->reqfilters);
  900. if(param->hdrfilterscli) myfree(param->hdrfilterscli);
  901. if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
  902. if(param->predatfilters) myfree(param->predatfilters);
  903. if(param->datfilterscli) myfree(param->datfilterscli);
  904. if(param->filters){
  905. if(param->nfilters)while(param->nfilters--){
  906. if(param->filters[param->nfilters].filter->filter_clear)
  907. (*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
  908. }
  909. myfree(param->filters);
  910. }
  911. if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param);
  912. #endif
  913. if(param->srv){
  914. pthread_mutex_lock(&param->srv->counter_mutex);
  915. if(param->prev){
  916. param->prev->next = param->next;
  917. }
  918. else
  919. param->srv->child = param->next;
  920. if(param->next){
  921. param->next->prev = param->prev;
  922. }
  923. (param->srv->childcount)--;
  924. pthread_mutex_unlock(&param->srv->counter_mutex);
  925. }
  926. if(param->hostname) myfree(param->hostname);
  927. if(param->username) myfree(param->username);
  928. if(param->password) myfree(param->password);
  929. if(param->extusername) myfree(param->extusername);
  930. if(param->extpassword) myfree(param->extpassword);
  931. myfree(param);
  932. }
  933. #ifndef STDMAIN
  934. static void * itcopy (void * from, size_t size){
  935. void * ret;
  936. if(!from) return NULL;
  937. ret = myalloc(size);
  938. if(ret) memcpy(ret, from, size);
  939. return ret;
  940. }
  941. struct auth * copyauth (struct auth * authfuncs){
  942. struct auth * newauth = NULL;
  943. newauth = authfuncs = itcopy(authfuncs, sizeof(struct auth));
  944. for( ; authfuncs; authfuncs = authfuncs->next = itcopy(authfuncs->next, sizeof(struct auth)));
  945. return newauth;
  946. }
  947. struct ace * copyacl (struct ace *ac){
  948. struct ace * ret = NULL;
  949. struct iplist *ipl;
  950. struct portlist *pl;
  951. struct userlist *ul;
  952. struct chain *ch;
  953. struct period *pel;
  954. struct hostname *hst;
  955. ret = ac = itcopy(ac, sizeof(struct ace));
  956. for( ; ac; ac = ac->next = itcopy(ac->next, sizeof(struct ace))){
  957. ac->src = itcopy(ac->src, sizeof(struct iplist));
  958. for(ipl = ac->src; ipl; ipl = ipl->next = itcopy(ipl->next, sizeof(struct iplist)));
  959. ac->dst = itcopy(ac->dst, sizeof(struct iplist));
  960. for(ipl = ac->dst; ipl; ipl = ipl->next = itcopy(ipl->next, sizeof(struct iplist)));
  961. ac->ports = itcopy(ac->ports, sizeof(struct portlist));
  962. for(pl = ac->ports; pl; pl = pl->next = itcopy(pl->next, sizeof(struct portlist)));
  963. ac->periods = itcopy(ac->periods, sizeof(struct period));
  964. for(pel = ac->periods; pel; pel = pel->next = itcopy(pel->next, sizeof(struct period)));
  965. ac->users = itcopy(ac->users, sizeof(struct userlist));
  966. for(ul = ac->users; ul; ul = ul->next = itcopy(ul->next, sizeof(struct userlist))){
  967. if(ul->user) ul->user = (unsigned char*)mystrdup((char *)ul->user);
  968. }
  969. ac->dstnames = itcopy(ac->dstnames, sizeof(struct hostname));
  970. for(hst = ac->dstnames; hst; hst = hst->next = itcopy(hst->next, sizeof(struct hostname))){
  971. if(hst->name) hst->name = (unsigned char*)mystrdup((char *)hst->name);
  972. }
  973. ac->chains = itcopy(ac->chains, sizeof(struct chain));
  974. for(ch = ac->chains; ch; ch = ch->next = itcopy(ch->next, sizeof(struct chain))){
  975. if(ch->extuser)ch->extuser = (unsigned char*)mystrdup((char *)ch->extuser);
  976. if(ch->extpass)ch->extpass = (unsigned char*)mystrdup((char *)ch->extpass);
  977. if(ch->exthost)ch->exthost = (unsigned char*)mystrdup((char *)ch->exthost);
  978. }
  979. }
  980. return ret;
  981. }
  982. void copyfilter (struct filter *filter, struct srvparam *srv){
  983. int nfilters = 0;
  984. if(!filter) return;
  985. for(srv->filter = filter; srv->filter; srv->filter = srv->filter->next) nfilters++;
  986. srv->filter = myalloc(sizeof(struct filter) * nfilters);
  987. if(!srv->filter) return;
  988. for(; filter; filter = filter->next){
  989. void *data = NULL;
  990. if(!filter->filter_open || !(data = (*filter->filter_open)(filter->data, srv))) continue;
  991. srv->filter[srv->nfilters] = *filter;
  992. srv->filter[srv->nfilters].data = data;
  993. if(srv->nfilters>0)srv->filter[srv->nfilters - 1].next = srv->filter + srv->nfilters;
  994. srv->nfilters++;
  995. if(filter->filter_request)srv->nreqfilters++;
  996. if(filter->filter_header_srv)srv->nhdrfilterssrv++;
  997. if(filter->filter_header_cli)srv->nhdrfilterscli++;
  998. if(filter->filter_predata)srv->npredatfilters++;
  999. if(filter->filter_data_srv)srv->ndatfilterssrv++;
  1000. if(filter->filter_data_cli)srv->ndatfilterscli++;
  1001. }
  1002. }
  1003. FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
  1004. FILTER_ACTION res=PASS;
  1005. FILTER_ACTION action;
  1006. int i;
  1007. if(!srv->nfilters) return PASS;
  1008. if(!(param->filters = myalloc(sizeof(struct filterp) * srv->nfilters)) ||
  1009. (srv->nreqfilters && !(param->reqfilters = myalloc(sizeof(struct filterp *) * srv->nreqfilters))) ||
  1010. (srv->nhdrfilterssrv && !(param->hdrfilterssrv = myalloc(sizeof(struct filterp *) * srv->nhdrfilterssrv))) ||
  1011. (srv->nhdrfilterscli && !(param->hdrfilterscli = myalloc(sizeof(struct filterp *) * srv->nhdrfilterscli))) ||
  1012. (srv->npredatfilters && !(param->predatfilters = myalloc(sizeof(struct filterp *) * srv->npredatfilters))) ||
  1013. (srv->ndatfilterssrv && !(param->datfilterssrv = myalloc(sizeof(struct filterp *) * srv->ndatfilterssrv))) ||
  1014. (srv->ndatfilterscli && !(param->datfilterscli = myalloc(sizeof(struct filterp *) * srv->ndatfilterscli)))
  1015. ){
  1016. param->res = 21;
  1017. return REJECT;
  1018. }
  1019. for(i=0; i<srv->nfilters; i++){
  1020. if(!srv->filter[i].filter_client)continue;
  1021. action = (*srv->filter[i].filter_client)(srv->filter[i].data, param, &param->filters[param->nfilters].data);
  1022. if(action == PASS) continue;
  1023. if(action > CONTINUE) return action;
  1024. param->filters[param->nfilters].filter = srv->filter + i;
  1025. if(srv->filter[i].filter_request)param->reqfilters[param->nreqfilters++] = param->filters + param->nfilters;
  1026. if(srv->filter[i].filter_header_cli)param->hdrfilterscli[param->nhdrfilterscli++] = param->filters + param->nfilters;
  1027. if(srv->filter[i].filter_header_srv)param->hdrfilterssrv[param->nhdrfilterssrv++] = param->filters + param->nfilters;
  1028. if(srv->filter[i].filter_predata)param->predatfilters[param->npredatfilters++] = param->filters + param->nfilters;
  1029. if(srv->filter[i].filter_data_cli)param->datfilterscli[param->ndatfilterscli++] = param->filters + param->nfilters;
  1030. if(srv->filter[i].filter_data_srv)param->datfilterssrv[param->ndatfilterssrv++] = param->filters + param->nfilters;
  1031. param->nfilters++;
  1032. }
  1033. return res;
  1034. }
  1035. void * itfree(void *data, void * retval){
  1036. myfree(data);
  1037. return retval;
  1038. }
  1039. void freeauth(struct auth * authfuncs){
  1040. for(; authfuncs; authfuncs = (struct auth *)itfree(authfuncs, authfuncs->next));
  1041. }
  1042. void freeacl(struct ace *ac){
  1043. struct iplist *ipl;
  1044. struct portlist *pl;
  1045. struct userlist *ul;
  1046. struct chain *ch;
  1047. struct period *pel;
  1048. struct hostname *hst;
  1049. for(; ac; ac = (struct ace *) itfree(ac, ac->next)){
  1050. for(ipl = ac->src; ipl; ipl = (struct iplist *)itfree(ipl, ipl->next));
  1051. for(ipl = ac->dst; ipl; ipl = (struct iplist *)itfree(ipl,ipl->next));
  1052. for(pl = ac->ports; pl; pl = (struct portlist *)itfree(pl, pl->next));
  1053. for(pel = ac->periods; pel; pel = (struct period *)itfree(pel, pel->next));
  1054. for(ul = ac->users; ul; ul = (struct userlist *)itfree(ul, ul->next)){
  1055. if(ul->user)myfree(ul->user);
  1056. }
  1057. for(hst = ac->dstnames; hst; hst = (struct hostname *)itfree(hst, hst->next)){
  1058. if(hst->name)myfree(hst->name);
  1059. }
  1060. for(ch = ac->chains; ch; ch = (struct chain *) itfree(ch, ch->next)){
  1061. if(ch->extuser) myfree(ch->extuser);
  1062. if(ch->extpass) myfree(ch->extpass);
  1063. if(ch->exthost) myfree(ch->exthost);
  1064. }
  1065. }
  1066. }
  1067. FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  1068. FILTER_ACTION action;
  1069. int i;
  1070. for(i=0; i<param->nreqfilters; i++){
  1071. action = (*param->reqfilters[i]->filter->filter_request)(param->reqfilters[i]->data, param, buf_p, bufsize_p, offset, length_p);
  1072. if(action!=CONTINUE) return action;
  1073. }
  1074. return PASS;
  1075. }
  1076. FILTER_ACTION handlehdrfilterssrv(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  1077. FILTER_ACTION action;
  1078. int i;
  1079. for(i=0; i<param->nhdrfilterssrv; i++){
  1080. action = (*param->hdrfilterssrv[i]->filter->filter_header_srv)(param->hdrfilterssrv[i]->data, param, buf_p, bufsize_p, offset, length_p);
  1081. if(action!=CONTINUE) return action;
  1082. }
  1083. return PASS;
  1084. }
  1085. FILTER_ACTION handlehdrfilterscli(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  1086. FILTER_ACTION action;
  1087. int i;
  1088. for(i = 0; i < param->nhdrfilterscli; i++){
  1089. action = (*param->hdrfilterscli[i]->filter->filter_header_cli)(param->hdrfilterscli[i]->data, param, buf_p, bufsize_p, offset, length_p);
  1090. if(action!=CONTINUE) return action;
  1091. }
  1092. return PASS;
  1093. }
  1094. #endif
  1095. FILTER_ACTION handlepredatflt(struct clientparam *cparam){
  1096. #ifndef STDMAIN
  1097. FILTER_ACTION action;
  1098. int i;
  1099. for(i=0; i<cparam->npredatfilters ;i++){
  1100. action = (*cparam->predatfilters[i]->filter->filter_predata)(cparam->predatfilters[i]->data, cparam);
  1101. if(action!=CONTINUE) return action;
  1102. }
  1103. #endif
  1104. return PASS;
  1105. }
  1106. FILTER_ACTION handledatfltcli(struct clientparam *cparam, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  1107. #ifndef STDMAIN
  1108. FILTER_ACTION action;
  1109. int i;
  1110. for(i=0; i<cparam->ndatfilterscli ;i++){
  1111. action = (*cparam->datfilterscli[i]->filter->filter_data_cli)(cparam->datfilterscli[i]->data, cparam, buf_p, bufsize_p, offset, length_p);
  1112. if(action!=CONTINUE) return action;
  1113. }
  1114. #endif
  1115. return PASS;
  1116. }
  1117. FILTER_ACTION handledatfltsrv(struct clientparam *cparam, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
  1118. FILTER_ACTION action;
  1119. int i;
  1120. for(i=0; i<cparam->ndatfilterssrv; i++){
  1121. action = (*cparam->datfilterssrv[i]->filter->filter_data_srv)(cparam->datfilterssrv[i]->data, cparam, buf_p, bufsize_p, offset, length_p);
  1122. if(action!=CONTINUE) return action;
  1123. }
  1124. return PASS;
  1125. }