proxymain.c 33 KB

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