io.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. /*
  2. Copyright (c) 2003-2006 by Juliusz Chroboczek
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. #include "polipo.h"
  20. #ifdef HAVE_IPv6
  21. #ifdef IPV6_PREFER_TEMPADDR
  22. #define HAVE_IPV6_PREFER_TEMPADDR 1
  23. #endif
  24. #endif
  25. #ifdef HAVE_IPV6_PREFER_TEMPADDR
  26. int useTemporarySourceAddress = 1;
  27. #endif
  28. AtomPtr proxyOutgoingAddress = NULL;
  29. void
  30. preinitIo()
  31. {
  32. #ifdef HAVE_IPV6_PREFER_TEMPADDR
  33. CONFIG_VARIABLE_SETTABLE(useTemporarySourceAddress, CONFIG_TRISTATE,
  34. configIntSetter,
  35. "Prefer IPv6 temporary source address.");
  36. #endif
  37. CONFIG_VARIABLE(proxyOutgoingAddress, CONFIG_ATOM_LOWER,
  38. "The IP address which the proxy connects from.");
  39. #ifdef HAVE_WINSOCK
  40. /* Load the winsock dll */
  41. WSADATA wsaData;
  42. WORD wVersionRequested = MAKEWORD(2, 2);
  43. int err = WSAStartup( wVersionRequested, &wsaData );
  44. if (err != 0) {
  45. do_log_error(L_ERROR, err, "Couldn't load winsock dll");
  46. exit(-1);
  47. }
  48. #endif
  49. return;
  50. }
  51. void
  52. initIo()
  53. {
  54. return;
  55. }
  56. FdEventHandlerPtr
  57. do_stream(int operation, int fd, int offset, char *buf, int len,
  58. int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr),
  59. void *data)
  60. {
  61. assert(len > offset || (operation & (IO_END | IO_IMMEDIATE)));
  62. return schedule_stream(operation, fd, offset,
  63. NULL, 0, buf, len, NULL, 0, NULL, 0, NULL,
  64. handler, data);
  65. }
  66. FdEventHandlerPtr
  67. do_stream_2(int operation, int fd, int offset,
  68. char *buf, int len, char *buf2, int len2,
  69. int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr),
  70. void *data)
  71. {
  72. assert(len + len2 > offset || (operation & (IO_END | IO_IMMEDIATE)));
  73. return schedule_stream(operation, fd, offset,
  74. NULL, 0, buf, len, buf2, len2, NULL, 0, NULL,
  75. handler, data);
  76. }
  77. FdEventHandlerPtr
  78. do_stream_3(int operation, int fd, int offset,
  79. char *buf, int len, char *buf2, int len2, char *buf3, int len3,
  80. int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr),
  81. void *data)
  82. {
  83. assert(len + len2 > offset || (operation & (IO_END | IO_IMMEDIATE)));
  84. return schedule_stream(operation, fd, offset,
  85. NULL, 0, buf, len, buf2, len2, buf3, len3, NULL,
  86. handler, data);
  87. }
  88. FdEventHandlerPtr
  89. do_stream_h(int operation, int fd, int offset,
  90. char *header, int hlen, char *buf, int len,
  91. int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr),
  92. void *data)
  93. {
  94. assert(hlen + len > offset || (operation & (IO_END | IO_IMMEDIATE)));
  95. return schedule_stream(operation, fd, offset,
  96. header, hlen, buf, len, NULL, 0, NULL, 0, NULL,
  97. handler, data);
  98. }
  99. FdEventHandlerPtr
  100. do_stream_buf(int operation, int fd, int offset, char **buf_location, int len,
  101. int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr),
  102. void *data)
  103. {
  104. assert((len > offset || (operation & (IO_END | IO_IMMEDIATE)))
  105. && len <= CHUNK_SIZE);
  106. return schedule_stream(operation, fd, offset,
  107. NULL, 0, *buf_location, len,
  108. NULL, 0, NULL, 0, buf_location,
  109. handler, data);
  110. }
  111. static int
  112. chunkHeaderLen(int i)
  113. {
  114. if(i <= 0)
  115. return 0;
  116. if(i < 0x10)
  117. return 3;
  118. else if(i < 0x100)
  119. return 4;
  120. else if(i < 0x1000)
  121. return 5;
  122. else if(i < 0x10000)
  123. return 6;
  124. else
  125. abort();
  126. }
  127. static int
  128. chunkHeader(char *buf, int buflen, int i)
  129. {
  130. int n;
  131. if(i <= 0)
  132. return 0;
  133. n = snprintf(buf, buflen, "%x\r\n", i);
  134. return n;
  135. }
  136. FdEventHandlerPtr
  137. schedule_stream(int operation, int fd, int offset,
  138. char *header, int hlen,
  139. char *buf, int len, char *buf2, int len2, char *buf3, int len3,
  140. char **buf_location,
  141. int (*handler)(int, FdEventHandlerPtr, StreamRequestPtr),
  142. void *data)
  143. {
  144. StreamRequestRec request;
  145. FdEventHandlerPtr event;
  146. int done;
  147. request.operation = operation;
  148. request.fd = fd;
  149. if(len3) {
  150. assert(hlen == 0 && buf_location == NULL);
  151. request.u.b.len3 = len3;
  152. request.u.b.buf3 = buf3;
  153. request.operation |= IO_BUF3;
  154. } else if(buf_location) {
  155. assert(hlen == 0);
  156. request.u.l.buf_location = buf_location;
  157. request.operation |= IO_BUF_LOCATION;
  158. } else {
  159. request.u.h.hlen = hlen;
  160. request.u.h.header = header;
  161. }
  162. request.buf = buf;
  163. request.len = len;
  164. request.buf2 = buf2;
  165. request.len2 = len2;
  166. if((operation & IO_CHUNKED) ||
  167. (!(request.operation & (IO_BUF3 | IO_BUF_LOCATION)) && hlen > 0)) {
  168. assert(offset == 0);
  169. request.offset = -hlen;
  170. if(operation & IO_CHUNKED)
  171. request.offset += -chunkHeaderLen(len + len2);
  172. } else {
  173. request.offset = offset;
  174. }
  175. request.handler = handler;
  176. request.data = data;
  177. event = makeFdEvent(fd,
  178. (operation & IO_MASK) == IO_WRITE ?
  179. POLLOUT : POLLIN,
  180. do_scheduled_stream,
  181. sizeof(StreamRequestRec), &request);
  182. if(!event) {
  183. done = (*handler)(-ENOMEM, NULL, &request);
  184. assert(done);
  185. return NULL;
  186. }
  187. if(!(operation & IO_NOTNOW)) {
  188. done = event->handler(0, event);
  189. if(done) {
  190. free(event);
  191. return NULL;
  192. }
  193. }
  194. if(operation & IO_IMMEDIATE) {
  195. assert(hlen == 0 && !(operation & IO_CHUNKED));
  196. done = (*handler)(0, event, &request);
  197. if(done) {
  198. free(event);
  199. return NULL;
  200. }
  201. }
  202. event = registerFdEventHelper(event);
  203. return event;
  204. }
  205. static const char *endChunkTrailer = "\r\n0\r\n\r\n";
  206. int
  207. do_scheduled_stream(int status, FdEventHandlerPtr event)
  208. {
  209. StreamRequestPtr request = (StreamRequestPtr)&event->data;
  210. int rc, done, i;
  211. struct iovec iov[6];
  212. int chunk_header_len;
  213. char chunk_header[10];
  214. int len12 = request->len + request->len2;
  215. int len123 =
  216. request->len + request->len2 +
  217. ((request->operation & IO_BUF3) ? request->u.b.len3 : 0);
  218. if(status) {
  219. done = request->handler(status, event, request);
  220. return done;
  221. }
  222. i = 0;
  223. if(request->offset < 0) {
  224. assert((request->operation & (IO_MASK | IO_BUF3 | IO_BUF_LOCATION)) ==
  225. IO_WRITE);
  226. if(request->operation & IO_CHUNKED) {
  227. chunk_header_len = chunkHeaderLen(len123);
  228. } else {
  229. chunk_header_len = 0;
  230. }
  231. if(request->offset < -chunk_header_len) {
  232. assert(request->offset >= -(request->u.h.hlen + chunk_header_len));
  233. iov[i].iov_base = request->u.h.header;
  234. iov[i].iov_len = -request->offset - chunk_header_len;
  235. i++;
  236. }
  237. if(chunk_header_len > 0) {
  238. chunkHeader(chunk_header, 10, len123);
  239. if(request->offset < -chunk_header_len) {
  240. iov[i].iov_base = chunk_header;
  241. iov[i].iov_len = chunk_header_len;
  242. } else {
  243. iov[i].iov_base = chunk_header +
  244. chunk_header_len + request->offset;
  245. iov[i].iov_len = -request->offset;
  246. }
  247. i++;
  248. }
  249. }
  250. if(request->len > 0) {
  251. if(request->buf == NULL &&
  252. (request->operation & IO_BUF_LOCATION)) {
  253. assert(*request->u.l.buf_location == NULL);
  254. request->buf = *request->u.l.buf_location = get_chunk();
  255. if(request->buf == NULL) {
  256. done = request->handler(-ENOMEM, event, request);
  257. return done;
  258. }
  259. }
  260. if(request->offset <= 0) {
  261. iov[i].iov_base = request->buf;
  262. iov[i].iov_len = request->len;
  263. i++;
  264. } else if(request->offset < request->len) {
  265. iov[i].iov_base = request->buf + request->offset;
  266. iov[i].iov_len = request->len - request->offset;
  267. i++;
  268. }
  269. }
  270. if(request->len2 > 0) {
  271. if(request->offset <= request->len) {
  272. iov[i].iov_base = request->buf2;
  273. iov[i].iov_len = request->len2;
  274. i++;
  275. } else if(request->offset < request->len + request->len2) {
  276. iov[i].iov_base = request->buf2 + request->offset - request->len;
  277. iov[i].iov_len = request->len2 - request->offset + request->len;
  278. i++;
  279. }
  280. }
  281. if((request->operation & IO_BUF3) && request->u.b.len3 > 0) {
  282. if(request->offset <= len12) {
  283. iov[i].iov_base = request->u.b.buf3;
  284. iov[i].iov_len = request->u.b.len3;
  285. i++;
  286. } else if(request->offset < len12 + request->u.b.len3) {
  287. iov[i].iov_base = request->u.b.buf3 + request->offset - len12;
  288. iov[i].iov_len = request->u.b.len3 - request->offset + len12;
  289. i++;
  290. }
  291. }
  292. if((request->operation & IO_CHUNKED)) {
  293. int l;
  294. const char *trailer;
  295. if(request->operation & IO_END) {
  296. if(len123 == 0) {
  297. trailer = endChunkTrailer + 2;
  298. l = 5;
  299. } else {
  300. trailer = endChunkTrailer;
  301. l = 7;
  302. }
  303. } else {
  304. trailer = endChunkTrailer;
  305. l = 2;
  306. }
  307. if(request->offset <= len123) {
  308. iov[i].iov_base = (char*)trailer;
  309. iov[i].iov_len = l;
  310. i++;
  311. } else if(request->offset < len123 + l) {
  312. iov[i].iov_base =
  313. (char*)endChunkTrailer + request->offset - len123;
  314. iov[i].iov_len = l - request->offset + len123;
  315. i++;
  316. }
  317. }
  318. assert(i > 0);
  319. if((request->operation & IO_MASK) == IO_WRITE) {
  320. if(i > 1)
  321. rc = WRITEV(request->fd, iov, i);
  322. else
  323. rc = WRITE(request->fd, iov[0].iov_base, iov[0].iov_len);
  324. } else {
  325. if(i > 1)
  326. rc = READV(request->fd, iov, i);
  327. else
  328. rc = READ(request->fd, iov[0].iov_base, iov[0].iov_len);
  329. }
  330. if(rc > 0) {
  331. request->offset += rc;
  332. if(request->offset < 0) return 0;
  333. done = request->handler(0, event, request);
  334. return done;
  335. } else if(rc == 0 || errno == EPIPE) {
  336. done = request->handler(1, event, request);
  337. } else if(errno == EAGAIN || errno == EINTR) {
  338. return 0;
  339. } else if(errno == EFAULT || errno == EBADF) {
  340. abort();
  341. } else {
  342. done = request->handler(-errno, event, request);
  343. }
  344. assert(done);
  345. return done;
  346. }
  347. int
  348. streamRequestDone(StreamRequestPtr request)
  349. {
  350. int len123 =
  351. request->len + request->len2 +
  352. ((request->operation & IO_BUF3) ? request->u.b.len3 : 0);
  353. if(request->offset < 0)
  354. return 0;
  355. else if(request->offset < len123)
  356. return 0;
  357. else if(request->operation & IO_CHUNKED) {
  358. if(request->operation & IO_END) {
  359. if(request->offset < len123 + (len123 ? 7 : 5))
  360. return 0;
  361. } else {
  362. if(request->offset < len123 + 2)
  363. return 0;
  364. }
  365. }
  366. return 1;
  367. }
  368. static int
  369. serverSocket_outgoingIP(int fd)
  370. {
  371. int rc;
  372. unsigned long int bind_addr_saddr = inet_addr (proxyOutgoingAddress->string);
  373. struct sockaddr_in local_sockaddr_in[] = {{ 0 }};
  374. local_sockaddr_in->sin_family = AF_INET;
  375. local_sockaddr_in->sin_addr.s_addr = bind_addr_saddr;
  376. local_sockaddr_in->sin_port = htons (0);
  377. rc = bind(fd, (struct sockaddr *)local_sockaddr_in, sizeof (struct sockaddr));
  378. if(rc != 0) {
  379. do_log_error(L_WARN, errno, "Couldn't bind outgoing IP %s", proxyOutgoingAddress->string);
  380. }
  381. return rc;
  382. }
  383. static int
  384. serverSocket(int af)
  385. {
  386. int fd, rc;
  387. if(af == 4) {
  388. fd = socket(PF_INET, SOCK_STREAM, 0);
  389. } else if(af == 6) {
  390. #ifdef HAVE_IPv6
  391. fd = socket(PF_INET6, SOCK_STREAM, 0);
  392. #else
  393. fd = -1;
  394. errno = EAFNOSUPPORT;
  395. #endif
  396. } else {
  397. abort();
  398. }
  399. if(fd >= 0) {
  400. if(proxyOutgoingAddress != NULL) {
  401. serverSocket_outgoingIP(fd);
  402. }
  403. rc = setNonblocking(fd, 1);
  404. if(rc < 0) {
  405. int errno_save = errno;
  406. CLOSE(fd);
  407. errno = errno_save;
  408. return -1;
  409. }
  410. #ifdef HAVE_IPV6_PREFER_TEMPADDR
  411. if (af == 6 && useTemporarySourceAddress != 1) {
  412. int value;
  413. value = (useTemporarySourceAddress == 2) ? 1 : 0;
  414. rc = setsockopt(fd, IPPROTO_IPV6, IPV6_PREFER_TEMPADDR,
  415. &value, sizeof(value));
  416. if (rc < 0) {
  417. /* no error, warning only */
  418. do_log_error(L_WARN, errno, "Couldn't set IPV6CTL_USETEMPADDR");
  419. }
  420. }
  421. #endif
  422. }
  423. return fd;
  424. }
  425. FdEventHandlerPtr
  426. do_connect(AtomPtr addr, int index, int port,
  427. int (*handler)(int, FdEventHandlerPtr, ConnectRequestPtr),
  428. void *data)
  429. {
  430. ConnectRequestRec request;
  431. FdEventHandlerPtr event;
  432. int done, fd, af;
  433. assert(addr->length > 0 && addr->string[0] == DNS_A);
  434. assert(addr->length % sizeof(HostAddressRec) == 1);
  435. if(index >= (addr->length - 1)/ sizeof(HostAddressRec))
  436. index = 0;
  437. request.firstindex = index;
  438. request.port = port;
  439. request.handler = handler;
  440. request.data = data;
  441. again:
  442. af = addr->string[1 + index * sizeof(HostAddressRec)];
  443. fd = serverSocket(af);
  444. request.fd = fd;
  445. request.af = af;
  446. request.addr = addr;
  447. request.index = index;
  448. if(fd < 0) {
  449. int n = (addr->length - 1) / sizeof(HostAddressRec);
  450. if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
  451. if((index + 1) % n != request.firstindex) {
  452. index = (index + 1) % n;
  453. goto again;
  454. }
  455. }
  456. do_log_error(L_ERROR, errno, "Couldn't create socket");
  457. done = (*handler)(-errno, NULL, &request);
  458. assert(done);
  459. return NULL;
  460. }
  461. /* POLLIN is apparently needed on Windows */
  462. event = registerFdEvent(fd, POLLIN | POLLOUT,
  463. do_scheduled_connect,
  464. sizeof(ConnectRequestRec), &request);
  465. if(event == NULL) {
  466. done = (*handler)(-ENOMEM, NULL, &request);
  467. assert(done);
  468. return NULL;
  469. }
  470. done = event->handler(0, event);
  471. if(done) {
  472. unregisterFdEvent(event);
  473. return NULL;
  474. }
  475. return event;
  476. }
  477. int
  478. do_scheduled_connect(int status, FdEventHandlerPtr event)
  479. {
  480. ConnectRequestPtr request = (ConnectRequestPtr)&event->data;
  481. AtomPtr addr = request->addr;
  482. int done;
  483. int rc;
  484. HostAddressPtr host;
  485. struct sockaddr_in servaddr;
  486. #ifdef HAVE_IPv6
  487. struct sockaddr_in6 servaddr6;
  488. #endif
  489. assert(addr->length > 0 && addr->string[0] == DNS_A);
  490. assert(addr->length % sizeof(HostAddressRec) == 1);
  491. assert(request->index < (addr->length - 1) / sizeof(HostAddressRec));
  492. if(status) {
  493. done = request->handler(status, event, request);
  494. if(done) {
  495. releaseAtom(addr);
  496. request->addr = NULL;
  497. return 1;
  498. }
  499. return 0;
  500. }
  501. again:
  502. host = (HostAddressPtr)&addr->string[1 +
  503. request->index *
  504. sizeof(HostAddressRec)];
  505. if(host->af != request->af) {
  506. int newfd;
  507. /* Ouch. Our socket has a different protocol than the host
  508. address. */
  509. CLOSE(request->fd);
  510. newfd = serverSocket(host->af);
  511. if(newfd < 0) {
  512. if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
  513. int n = request->addr->length / sizeof(HostAddressRec);
  514. if((request->index + 1) % n != request->firstindex) {
  515. request->index = (request->index + 1) % n;
  516. goto again;
  517. }
  518. }
  519. request->fd = -1;
  520. done = request->handler(-errno, event, request);
  521. assert(done);
  522. return 1;
  523. }
  524. if(newfd != request->fd) {
  525. request->fd = dup2(newfd, request->fd);
  526. CLOSE(newfd);
  527. if(request->fd < 0) {
  528. done = request->handler(-errno, event, request);
  529. assert(done);
  530. return 1;
  531. }
  532. }
  533. request->af = host->af;
  534. }
  535. switch(host->af) {
  536. case 4:
  537. memset(&servaddr, 0, sizeof(servaddr));
  538. servaddr.sin_family = AF_INET;
  539. servaddr.sin_port = htons(request->port);
  540. memcpy(&servaddr.sin_addr, &host->data, sizeof(struct in_addr));
  541. rc = connect(request->fd,
  542. (struct sockaddr*)&servaddr, sizeof(servaddr));
  543. break;
  544. case 6:
  545. #ifdef HAVE_IPv6
  546. memset(&servaddr6, 0, sizeof(servaddr6));
  547. servaddr6.sin6_family = AF_INET6;
  548. servaddr6.sin6_port = htons(request->port);
  549. memcpy(&servaddr6.sin6_addr, &host->data, sizeof(struct in6_addr));
  550. rc = connect(request->fd,
  551. (struct sockaddr*)&servaddr6, sizeof(servaddr6));
  552. #else
  553. rc = -1;
  554. errno = EAFNOSUPPORT;
  555. #endif
  556. break;
  557. default:
  558. abort();
  559. }
  560. if(rc >= 0 || errno == EISCONN) {
  561. done = request->handler(1, event, request);
  562. assert(done);
  563. releaseAtom(request->addr);
  564. request->addr = NULL;
  565. return 1;
  566. }
  567. if(errno == EINPROGRESS || errno == EINTR) {
  568. return 0;
  569. } else if(errno == EFAULT || errno == EBADF) {
  570. abort();
  571. } else {
  572. int n = request->addr->length / sizeof(HostAddressRec);
  573. if((request->index + 1) % n != request->firstindex) {
  574. request->index = (request->index + 1) % n;
  575. goto again;
  576. }
  577. done = request->handler(-errno, event, request);
  578. assert(done);
  579. releaseAtom(request->addr);
  580. request->addr = NULL;
  581. return 1;
  582. }
  583. }
  584. FdEventHandlerPtr
  585. do_accept(int fd,
  586. int (*handler)(int, FdEventHandlerPtr, AcceptRequestPtr),
  587. void *data)
  588. {
  589. FdEventHandlerPtr event;
  590. int done;
  591. event = schedule_accept(fd, handler, data);
  592. if(event == NULL) {
  593. done = (*handler)(-ENOMEM, NULL, NULL);
  594. assert(done);
  595. }
  596. /* But don't invoke it now - this will delay accept if under load. */
  597. return event;
  598. }
  599. FdEventHandlerPtr
  600. schedule_accept(int fd,
  601. int (*handler)(int, FdEventHandlerPtr, AcceptRequestPtr),
  602. void *data)
  603. {
  604. FdEventHandlerPtr event;
  605. AcceptRequestRec request;
  606. int done;
  607. request.fd = fd;
  608. request.handler = handler;
  609. request.data = data;
  610. event = registerFdEvent(fd, POLLIN,
  611. do_scheduled_accept, sizeof(request), &request);
  612. if(!event) {
  613. done = (*handler)(-ENOMEM, NULL, NULL);
  614. assert(done);
  615. }
  616. return event;
  617. }
  618. int
  619. do_scheduled_accept(int status, FdEventHandlerPtr event)
  620. {
  621. AcceptRequestPtr request = (AcceptRequestPtr)&event->data;
  622. int rc, done;
  623. socklen_t len;
  624. struct sockaddr_in addr;
  625. if(status) {
  626. done = request->handler(status, event, request);
  627. if(done) return done;
  628. }
  629. len = sizeof(struct sockaddr_in);
  630. rc = accept(request->fd, (struct sockaddr*)&addr, &len);
  631. if(rc >= 0)
  632. done = request->handler(rc, event, request);
  633. else
  634. done = request->handler(-errno, event, request);
  635. return done;
  636. }
  637. FdEventHandlerPtr
  638. create_listener(char *address, int port,
  639. int (*handler)(int, FdEventHandlerPtr, AcceptRequestPtr),
  640. void *data)
  641. {
  642. int fd, rc;
  643. int one = 1;
  644. int done;
  645. struct sockaddr_in addr;
  646. #ifdef HAVE_IPv6
  647. int inet6 = 1;
  648. struct sockaddr_in6 addr6;
  649. #else
  650. int inet6 = 0;
  651. #endif
  652. if(inet6 && address) {
  653. struct in_addr buf;
  654. rc = inet_aton(address, &buf);
  655. if(rc == 1)
  656. inet6 = 0;
  657. }
  658. fd = -1;
  659. errno = EAFNOSUPPORT;
  660. #ifdef HAVE_IPv6
  661. if(inet6) {
  662. fd = socket(PF_INET6, SOCK_STREAM, 0);
  663. }
  664. #endif
  665. if(fd < 0 && (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)) {
  666. inet6 = 0;
  667. fd = socket(PF_INET, SOCK_STREAM, 0);
  668. }
  669. if(fd < 0) {
  670. done = (*handler)(-errno, NULL, NULL);
  671. assert(done);
  672. return NULL;
  673. }
  674. #ifndef WIN32
  675. /* on WIN32 SO_REUSEADDR allows two sockets bind to the same port */
  676. rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
  677. if(rc < 0) do_log_error(L_WARN, errno, "Couldn't set SO_REUSEADDR");
  678. #endif
  679. if(inet6) {
  680. #ifdef HAVE_IPv6
  681. rc = setV6only(fd, 0);
  682. if(rc < 0)
  683. /* Reportedly OpenBSD returns an error for that. So only
  684. log it as a debugging message. */
  685. do_log_error(D_CLIENT_CONN, errno, "Couldn't reset IPV6_V6ONLY");
  686. memset(&addr6, 0, sizeof(addr6));
  687. rc = inet_pton(AF_INET6, address, &addr6.sin6_addr);
  688. if(rc != 1) {
  689. done = (*handler)(rc == 0 ? -ESYNTAX : -errno, NULL, NULL);
  690. assert(done);
  691. return NULL;
  692. }
  693. addr6.sin6_family = AF_INET6;
  694. addr6.sin6_port = htons(port);
  695. rc = bind(fd, (struct sockaddr*)&addr6, sizeof(addr6));
  696. #else
  697. rc = -1;
  698. errno = EAFNOSUPPORT;
  699. #endif
  700. } else {
  701. memset(&addr, 0, sizeof(addr));
  702. rc = inet_aton(address, &addr.sin_addr);
  703. if(rc != 1) {
  704. done = (*handler)(rc == 0 ? -ESYNTAX : -errno, NULL, NULL);
  705. assert(done);
  706. return NULL;
  707. }
  708. addr.sin_family = AF_INET;
  709. addr.sin_port = htons(port);
  710. rc = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
  711. }
  712. if(rc < 0) {
  713. do_log_error(L_ERROR, errno, "Couldn't bind");
  714. CLOSE(fd);
  715. done = (*handler)(-errno, NULL, NULL);
  716. assert(done);
  717. return NULL;
  718. }
  719. rc = setNonblocking(fd, 1);
  720. if(rc < 0) {
  721. do_log_error(L_ERROR, errno, "Couldn't set non blocking mode");
  722. CLOSE(fd);
  723. done = (*handler)(-errno, NULL, NULL);
  724. assert(done);
  725. return NULL;
  726. }
  727. rc = listen(fd, 1024);
  728. if(rc < 0) {
  729. do_log_error(L_ERROR, errno, "Couldn't listen");
  730. CLOSE(fd);
  731. done = (*handler)(-errno, NULL, NULL);
  732. assert(done);
  733. return NULL;
  734. }
  735. do_log(L_INFO, "Established listening socket on port %d.\n", port);
  736. return schedule_accept(fd, handler, data);
  737. }
  738. #ifndef SOL_TCP
  739. /* BSD */
  740. #define SOL_TCP IPPROTO_TCP
  741. #endif
  742. int
  743. setNonblocking(int fd, int nonblocking)
  744. {
  745. #ifdef WIN32 /*MINGW*/
  746. return win32_setnonblocking(fd, nonblocking);
  747. #else
  748. int rc;
  749. rc = fcntl(fd, F_GETFL, 0);
  750. if(rc < 0)
  751. return -1;
  752. rc = fcntl(fd, F_SETFL, nonblocking?(rc | O_NONBLOCK):(rc & ~O_NONBLOCK));
  753. if(rc < 0)
  754. return -1;
  755. return 0;
  756. #endif
  757. }
  758. int
  759. setNodelay(int fd, int nodelay)
  760. {
  761. int val = nodelay ? 1 : 0;
  762. int rc;
  763. rc = setsockopt(fd, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
  764. if(rc < 0)
  765. return -1;
  766. return 0;
  767. }
  768. #ifdef IPV6_V6ONLY
  769. int
  770. setV6only(int fd, int v6only)
  771. {
  772. int val = v6only ? 1 : 0;
  773. int rc;
  774. rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val));
  775. if(rc < 0)
  776. return -1;
  777. return 0;
  778. }
  779. #else
  780. int
  781. setV6only(int fd, int v6only)
  782. {
  783. return 0;
  784. }
  785. #endif
  786. typedef struct _LingeringClose {
  787. int fd;
  788. FdEventHandlerPtr handler;
  789. TimeEventHandlerPtr timeout;
  790. } LingeringCloseRec, *LingeringClosePtr;
  791. static int
  792. lingeringCloseTimeoutHandler(TimeEventHandlerPtr event)
  793. {
  794. LingeringClosePtr l = *(LingeringClosePtr*)event->data;
  795. assert(l->timeout == event);
  796. l->timeout = NULL;
  797. if(l->handler)
  798. pokeFdEvent(l->fd, -ESHUTDOWN, POLLIN | POLLOUT);
  799. else {
  800. CLOSE(l->fd);
  801. free(l);
  802. }
  803. return 1;
  804. }
  805. static int
  806. lingeringCloseHandler(int status, FdEventHandlerPtr event)
  807. {
  808. LingeringClosePtr l = *(LingeringClosePtr*)event->data;
  809. char buf[17];
  810. int rc;
  811. assert(l->handler == event);
  812. l->handler = NULL;
  813. if(status && status != -EDOGRACEFUL)
  814. goto done;
  815. rc = READ(l->fd, &buf, 17);
  816. if(rc == 0 || (rc < 0 && errno != EAGAIN && errno != EINTR))
  817. goto done;
  818. /* The client is still sending data. Ignore it in order to let
  819. TCP's flow control do its work. The timeout will close the
  820. connection. */
  821. return 1;
  822. done:
  823. if(l->timeout) {
  824. cancelTimeEvent(l->timeout);
  825. l->timeout = NULL;
  826. }
  827. CLOSE(l->fd);
  828. free(l);
  829. return 1;
  830. }
  831. int
  832. lingeringClose(int fd)
  833. {
  834. int rc;
  835. LingeringClosePtr l;
  836. rc = shutdown(fd, 1);
  837. if(rc < 0) {
  838. if(errno != ENOTCONN) {
  839. do_log_error(L_ERROR, errno, "Shutdown failed");
  840. } else if(errno == EFAULT || errno == EBADF) {
  841. abort();
  842. }
  843. CLOSE(fd);
  844. return 1;
  845. }
  846. l = malloc(sizeof(LingeringCloseRec));
  847. if(l == NULL)
  848. goto fail;
  849. l->fd = fd;
  850. l->handler = NULL;
  851. l->timeout = NULL;
  852. l->timeout = scheduleTimeEvent(10, lingeringCloseTimeoutHandler,
  853. sizeof(LingeringClosePtr), &l);
  854. if(l->timeout == NULL) {
  855. free(l);
  856. goto fail;
  857. }
  858. l->handler = registerFdEvent(fd, POLLIN,
  859. lingeringCloseHandler,
  860. sizeof(LingeringClosePtr), &l);
  861. if(l->handler == NULL) {
  862. do_log(L_ERROR, "Couldn't schedule lingering close handler.\n");
  863. /* But don't close -- the timeout will do its work. */
  864. }
  865. return 1;
  866. fail:
  867. do_log(L_ERROR, "Couldn't schedule lingering close.\n");
  868. CLOSE(fd);
  869. return 1;
  870. }
  871. NetAddressPtr
  872. parseNetAddress(AtomListPtr list)
  873. {
  874. NetAddressPtr nl;
  875. int i, rc, rc6;
  876. char buf[100];
  877. struct in_addr ina;
  878. #ifdef HAVE_IPv6
  879. struct in6_addr ina6;
  880. #endif
  881. nl = malloc((list->length + 1) * sizeof(NetAddressRec));
  882. if(nl == NULL) {
  883. do_log(L_ERROR, "Couldn't allocate network list.\n");
  884. return NULL;
  885. }
  886. for(i = 0; i < list->length; i++) {
  887. int prefix;
  888. char *s = list->list[i]->string, *p;
  889. int n = list->list[i]->length;
  890. char *suffix;
  891. while(*s == ' ' || *s == '\t') {
  892. s++;
  893. n--;
  894. }
  895. if(n >= 100) {
  896. do_log(L_ERROR, "Network name too long.\n");
  897. goto fail;
  898. }
  899. p = memchr(s, '/', n);
  900. if(p) {
  901. memcpy(buf, s, p - s);
  902. buf[p - s] = '\0';
  903. prefix = strtol(p + 1, &suffix, 10);
  904. } else {
  905. char *s1, *s2;
  906. prefix = -1;
  907. strcpy(buf, s);
  908. s1 = strchr(s, ' ');
  909. s2 = strchr(s, '\t');
  910. if(s1 == NULL) suffix = s2;
  911. else if(s2 == NULL) suffix = s1;
  912. else if(s1 < s2) suffix = s1;
  913. else suffix = s2;
  914. if(suffix == NULL)
  915. suffix = s + n;
  916. }
  917. if(!isWhitespace(suffix)) {
  918. do_log(L_ERROR, "Couldn't parse network %s.\n", buf);
  919. goto fail;
  920. }
  921. rc = 0; rc6 = 0;
  922. rc = inet_aton(buf, &ina);
  923. #ifdef HAVE_IPv6
  924. if(rc == 0) {
  925. rc6 = inet_pton(AF_INET6, buf, &ina6);
  926. }
  927. #endif
  928. if(rc == 0 && rc6 == 0) {
  929. do_log(L_ERROR, "Couldn't parse network %s.\n", buf);
  930. goto fail;
  931. }
  932. nl[i].prefix = prefix;
  933. if(rc) {
  934. nl[i].af = 4;
  935. memcpy(nl[i].data, &ina, 4);
  936. } else {
  937. #ifdef HAVE_IPv6
  938. nl[i].af = 6;
  939. memcpy(nl[i].data, &ina6, 16);
  940. #else
  941. abort();
  942. #endif
  943. }
  944. }
  945. nl[i].af = 0;
  946. return nl;
  947. fail:
  948. free(nl);
  949. return NULL;
  950. }
  951. /* Returns 1 if the first n bits of a and b are equal */
  952. static int
  953. bitmatch(const unsigned char *a, const unsigned char *b, int n)
  954. {
  955. if(n >= 8) {
  956. if(memcmp(a, b, n / 8) != 0)
  957. return 0;
  958. }
  959. if(n % 8 != 0) {
  960. int mask = (~0) << (8 - n % 8);
  961. if((a[n / 8] & mask) != (b[n / 8] & mask))
  962. return 0;
  963. }
  964. return 1;
  965. }
  966. /* Returns 1 if the address in data is in list */
  967. static int
  968. match(int af, unsigned char *data, NetAddressPtr list)
  969. {
  970. int i;
  971. #ifdef HAVE_IPv6
  972. static const unsigned char v6mapped[] =
  973. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF };
  974. #endif
  975. i = 0;
  976. while(list[i].af != 0) {
  977. if(af == 4 && list[i].af == 4) {
  978. if(bitmatch(data, list[i].data,
  979. list[i].prefix >= 0 ? list[i].prefix : 32))
  980. return 1;
  981. #ifdef HAVE_IPv6
  982. } else if(af == 6 && list[i].af == 6) {
  983. if(bitmatch(data, list[i].data,
  984. list[i].prefix >= 0 ? list[i].prefix : 128))
  985. return 1;
  986. } else if(af == 6 && list[i].af == 4) {
  987. if(bitmatch(data, v6mapped, 96)) {
  988. if(bitmatch(data + 12, list[i].data,
  989. list[i].prefix >= 0 ? list[i].prefix : 32))
  990. return 1;
  991. }
  992. } else if(af == 4 && list[i].af == 6) {
  993. if(bitmatch(list[i].data, v6mapped, 96)) {
  994. if(bitmatch(data, list[i].data + 12,
  995. list[i].prefix >= 96 ?
  996. list[i].prefix - 96 : 32))
  997. return 1;
  998. }
  999. #endif
  1000. } else {
  1001. abort();
  1002. }
  1003. i++;
  1004. }
  1005. return 0;
  1006. }
  1007. int
  1008. netAddressMatch(int fd, NetAddressPtr list)
  1009. {
  1010. int rc;
  1011. socklen_t len;
  1012. struct sockaddr_in sain;
  1013. #ifdef HAVE_IPv6
  1014. struct sockaddr_in6 sain6;
  1015. #endif
  1016. len = sizeof(sain);
  1017. rc = getpeername(fd, (struct sockaddr*)&sain, &len);
  1018. if(rc < 0) {
  1019. do_log_error(L_ERROR, errno, "Couldn't get peer name");
  1020. return -1;
  1021. }
  1022. if(sain.sin_family == AF_INET) {
  1023. return match(4, (unsigned char*)&sain.sin_addr, list);
  1024. #ifdef HAVE_IPv6
  1025. } else if(sain.sin_family == AF_INET6) {
  1026. len = sizeof(sain6);
  1027. rc = getpeername(fd, (struct sockaddr*)&sain6, &len);
  1028. if(rc < 0) {
  1029. do_log_error(L_ERROR, errno, "Couldn't get peer name");
  1030. return -1;
  1031. }
  1032. if(sain6.sin6_family != AF_INET6) {
  1033. do_log(L_ERROR, "Inconsistent peer name");
  1034. return -1;
  1035. }
  1036. return match(6, (unsigned char*)&sain6.sin6_addr, list);
  1037. #endif
  1038. } else {
  1039. do_log(L_ERROR, "Unknown address family %d\n", sain.sin_family);
  1040. return -1;
  1041. }
  1042. return 0;
  1043. }