PageRenderTime 61ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/connection.c

https://github.com/james-w/haproxy
C | 701 lines | 478 code | 98 blank | 125 comment | 183 complexity | ff46791d47409b92300b55b23a29cfd8 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. /*
  2. * Connection management functions
  3. *
  4. * Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. *
  11. */
  12. #include <errno.h>
  13. #include <common/compat.h>
  14. #include <common/config.h>
  15. #include <proto/connection.h>
  16. #include <proto/fd.h>
  17. #include <proto/frontend.h>
  18. #include <proto/proto_tcp.h>
  19. #include <proto/session.h>
  20. #include <proto/stream_interface.h>
  21. #ifdef USE_OPENSSL
  22. #include <proto/ssl_sock.h>
  23. #endif
  24. struct pool_head *pool2_connection;
  25. /* perform minimal intializations, report 0 in case of error, 1 if OK. */
  26. int init_connection()
  27. {
  28. pool2_connection = create_pool("connection", sizeof (struct connection), MEM_F_SHARED);
  29. return pool2_connection != NULL;
  30. }
  31. /* I/O callback for fd-based connections. It calls the read/write handlers
  32. * provided by the connection's sock_ops, which must be valid. It returns 0.
  33. */
  34. int conn_fd_handler(int fd)
  35. {
  36. struct connection *conn = fdtab[fd].owner;
  37. unsigned int flags;
  38. if (unlikely(!conn))
  39. return 0;
  40. conn_refresh_polling_flags(conn);
  41. flags = conn->flags & ~CO_FL_ERROR; /* ensure to call the wake handler upon error */
  42. process_handshake:
  43. /* The handshake callbacks are called in sequence. If either of them is
  44. * missing something, it must enable the required polling at the socket
  45. * layer of the connection. Polling state is not guaranteed when entering
  46. * these handlers, so any handshake handler which does not complete its
  47. * work must explicitly disable events it's not interested in. Error
  48. * handling is also performed here in order to reduce the number of tests
  49. * around.
  50. */
  51. while (unlikely(conn->flags & (CO_FL_HANDSHAKE | CO_FL_ERROR))) {
  52. if (unlikely(conn->flags & CO_FL_ERROR))
  53. goto leave;
  54. if (conn->flags & CO_FL_ACCEPT_PROXY)
  55. if (!conn_recv_proxy(conn, CO_FL_ACCEPT_PROXY))
  56. goto leave;
  57. if (conn->flags & CO_FL_SEND_PROXY)
  58. if (!conn_si_send_proxy(conn, CO_FL_SEND_PROXY))
  59. goto leave;
  60. #ifdef USE_OPENSSL
  61. if (conn->flags & CO_FL_SSL_WAIT_HS)
  62. if (!ssl_sock_handshake(conn, CO_FL_SSL_WAIT_HS))
  63. goto leave;
  64. #endif
  65. }
  66. /* Once we're purely in the data phase, we disable handshake polling */
  67. if (!(conn->flags & CO_FL_POLL_SOCK))
  68. __conn_sock_stop_both(conn);
  69. /* The data layer might not be ready yet (eg: when using embryonic
  70. * sessions). If we're about to move data, we must initialize it first.
  71. * The function may fail and cause the connection to be destroyed, thus
  72. * we must not use it anymore and should immediately leave instead.
  73. */
  74. if ((conn->flags & CO_FL_INIT_DATA) && conn->data->init(conn) < 0)
  75. return 0;
  76. /* The data transfer starts here and stops on error and handshakes. Note
  77. * that we must absolutely test conn->xprt at each step in case it suddenly
  78. * changes due to a quick unexpected close().
  79. */
  80. if (conn->xprt && fd_recv_ready(fd) &&
  81. ((conn->flags & (CO_FL_DATA_RD_ENA|CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE)) == CO_FL_DATA_RD_ENA)) {
  82. /* force detection of a flag change : it's impossible to have both
  83. * CONNECTED and WAIT_CONN so we're certain to trigger a change.
  84. */
  85. flags = CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED;
  86. conn->data->recv(conn);
  87. }
  88. if (conn->xprt && fd_send_ready(fd) &&
  89. ((conn->flags & (CO_FL_DATA_WR_ENA|CO_FL_WAIT_DATA|CO_FL_ERROR|CO_FL_HANDSHAKE)) == CO_FL_DATA_WR_ENA)) {
  90. /* force detection of a flag change : it's impossible to have both
  91. * CONNECTED and WAIT_CONN so we're certain to trigger a change.
  92. */
  93. flags = CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED;
  94. conn->data->send(conn);
  95. }
  96. /* It may happen during the data phase that a handshake is
  97. * enabled again (eg: SSL)
  98. */
  99. if (unlikely(conn->flags & (CO_FL_HANDSHAKE | CO_FL_ERROR)))
  100. goto process_handshake;
  101. if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN)) {
  102. /* still waiting for a connection to establish and nothing was
  103. * attempted yet to probe the connection. Then let's retry the
  104. * connect().
  105. */
  106. if (!tcp_connect_probe(conn))
  107. goto leave;
  108. }
  109. leave:
  110. /* The wake callback may be used to process a critical error and abort the
  111. * connection. If so, we don't want to go further as the connection will
  112. * have been released and the FD destroyed.
  113. */
  114. if ((conn->flags & CO_FL_WAKE_DATA) &&
  115. ((conn->flags ^ flags) & CO_FL_CONN_STATE) &&
  116. conn->data->wake(conn) < 0)
  117. return 0;
  118. /* Last check, verify if the connection just established */
  119. if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))
  120. conn->flags |= CO_FL_CONNECTED;
  121. /* remove the events before leaving */
  122. fdtab[fd].ev &= FD_POLL_STICKY;
  123. /* commit polling changes */
  124. conn_cond_update_polling(conn);
  125. return 0;
  126. }
  127. /* Update polling on connection <c>'s file descriptor depending on its current
  128. * state as reported in the connection's CO_FL_CURR_* flags, reports of EAGAIN
  129. * in CO_FL_WAIT_*, and the data layer expectations indicated by CO_FL_DATA_*.
  130. * The connection flags are updated with the new flags at the end of the
  131. * operation. Polling is totally disabled if an error was reported.
  132. */
  133. void conn_update_data_polling(struct connection *c)
  134. {
  135. unsigned int f = c->flags;
  136. if (!conn_ctrl_ready(c))
  137. return;
  138. /* update read status if needed */
  139. if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_DATA_RD_ENA)) == CO_FL_DATA_RD_ENA)) {
  140. fd_want_recv(c->t.sock.fd);
  141. f |= CO_FL_CURR_RD_ENA;
  142. }
  143. else if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_DATA_RD_ENA)) == CO_FL_CURR_RD_ENA)) {
  144. fd_stop_recv(c->t.sock.fd);
  145. f &= ~CO_FL_CURR_RD_ENA;
  146. }
  147. /* update write status if needed */
  148. if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_DATA_WR_ENA)) == CO_FL_DATA_WR_ENA)) {
  149. fd_want_send(c->t.sock.fd);
  150. f |= CO_FL_CURR_WR_ENA;
  151. }
  152. else if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_DATA_WR_ENA)) == CO_FL_CURR_WR_ENA)) {
  153. fd_stop_send(c->t.sock.fd);
  154. f &= ~CO_FL_CURR_WR_ENA;
  155. }
  156. c->flags = f;
  157. }
  158. /* Update polling on connection <c>'s file descriptor depending on its current
  159. * state as reported in the connection's CO_FL_CURR_* flags, reports of EAGAIN
  160. * in CO_FL_WAIT_*, and the sock layer expectations indicated by CO_FL_SOCK_*.
  161. * The connection flags are updated with the new flags at the end of the
  162. * operation. Polling is totally disabled if an error was reported.
  163. */
  164. void conn_update_sock_polling(struct connection *c)
  165. {
  166. unsigned int f = c->flags;
  167. if (!conn_ctrl_ready(c))
  168. return;
  169. /* update read status if needed */
  170. if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_SOCK_RD_ENA)) == CO_FL_SOCK_RD_ENA)) {
  171. fd_want_recv(c->t.sock.fd);
  172. f |= CO_FL_CURR_RD_ENA;
  173. }
  174. else if (unlikely((f & (CO_FL_CURR_RD_ENA|CO_FL_SOCK_RD_ENA)) == CO_FL_CURR_RD_ENA)) {
  175. fd_stop_recv(c->t.sock.fd);
  176. f &= ~CO_FL_CURR_RD_ENA;
  177. }
  178. /* update write status if needed */
  179. if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_SOCK_WR_ENA)) == CO_FL_SOCK_WR_ENA)) {
  180. fd_want_send(c->t.sock.fd);
  181. f |= CO_FL_CURR_WR_ENA;
  182. }
  183. else if (unlikely((f & (CO_FL_CURR_WR_ENA|CO_FL_SOCK_WR_ENA)) == CO_FL_CURR_WR_ENA)) {
  184. fd_stop_send(c->t.sock.fd);
  185. f &= ~CO_FL_CURR_WR_ENA;
  186. }
  187. c->flags = f;
  188. }
  189. /* This handshake handler waits a PROXY protocol header at the beginning of the
  190. * raw data stream. The header looks like this :
  191. *
  192. * "PROXY" <SP> PROTO <SP> SRC3 <SP> DST3 <SP> SRC4 <SP> <DST4> "\r\n"
  193. *
  194. * There must be exactly one space between each field. Fields are :
  195. * - PROTO : layer 4 protocol, which must be "TCP4" or "TCP6".
  196. * - SRC3 : layer 3 (eg: IP) source address in standard text form
  197. * - DST3 : layer 3 (eg: IP) destination address in standard text form
  198. * - SRC4 : layer 4 (eg: TCP port) source address in standard text form
  199. * - DST4 : layer 4 (eg: TCP port) destination address in standard text form
  200. *
  201. * This line MUST be at the beginning of the buffer and MUST NOT wrap.
  202. *
  203. * The header line is small and in all cases smaller than the smallest normal
  204. * TCP MSS. So it MUST always be delivered as one segment, which ensures we
  205. * can safely use MSG_PEEK and avoid buffering.
  206. *
  207. * Once the data is fetched, the values are set in the connection's address
  208. * fields, and data are removed from the socket's buffer. The function returns
  209. * zero if it needs to wait for more data or if it fails, or 1 if it completed
  210. * and removed itself.
  211. */
  212. int conn_recv_proxy(struct connection *conn, int flag)
  213. {
  214. char *line, *end;
  215. struct proxy_hdr_v2 *hdr_v2;
  216. const char v2sig[] = PP2_SIGNATURE;
  217. /* we might have been called just after an asynchronous shutr */
  218. if (conn->flags & CO_FL_SOCK_RD_SH)
  219. goto fail;
  220. if (!conn_ctrl_ready(conn))
  221. goto fail;
  222. if (!fd_recv_ready(conn->t.sock.fd))
  223. return 0;
  224. do {
  225. trash.len = recv(conn->t.sock.fd, trash.str, trash.size, MSG_PEEK);
  226. if (trash.len < 0) {
  227. if (errno == EINTR)
  228. continue;
  229. if (errno == EAGAIN) {
  230. fd_cant_recv(conn->t.sock.fd);
  231. return 0;
  232. }
  233. goto recv_abort;
  234. }
  235. } while (0);
  236. if (!trash.len) {
  237. /* client shutdown */
  238. conn->err_code = CO_ER_PRX_EMPTY;
  239. goto fail;
  240. }
  241. if (trash.len < 6)
  242. goto missing;
  243. line = trash.str;
  244. end = trash.str + trash.len;
  245. /* Decode a possible proxy request, fail early if it does not match */
  246. if (strncmp(line, "PROXY ", 6) != 0)
  247. goto not_v1;
  248. line += 6;
  249. if (trash.len < 9) /* shortest possible line */
  250. goto missing;
  251. if (!memcmp(line, "TCP4 ", 5) != 0) {
  252. u32 src3, dst3, sport, dport;
  253. line += 5;
  254. src3 = inetaddr_host_lim_ret(line, end, &line);
  255. if (line == end)
  256. goto missing;
  257. if (*line++ != ' ')
  258. goto bad_header;
  259. dst3 = inetaddr_host_lim_ret(line, end, &line);
  260. if (line == end)
  261. goto missing;
  262. if (*line++ != ' ')
  263. goto bad_header;
  264. sport = read_uint((const char **)&line, end);
  265. if (line == end)
  266. goto missing;
  267. if (*line++ != ' ')
  268. goto bad_header;
  269. dport = read_uint((const char **)&line, end);
  270. if (line > end - 2)
  271. goto missing;
  272. if (*line++ != '\r')
  273. goto bad_header;
  274. if (*line++ != '\n')
  275. goto bad_header;
  276. /* update the session's addresses and mark them set */
  277. ((struct sockaddr_in *)&conn->addr.from)->sin_family = AF_INET;
  278. ((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = htonl(src3);
  279. ((struct sockaddr_in *)&conn->addr.from)->sin_port = htons(sport);
  280. ((struct sockaddr_in *)&conn->addr.to)->sin_family = AF_INET;
  281. ((struct sockaddr_in *)&conn->addr.to)->sin_addr.s_addr = htonl(dst3);
  282. ((struct sockaddr_in *)&conn->addr.to)->sin_port = htons(dport);
  283. conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
  284. }
  285. else if (!memcmp(line, "TCP6 ", 5) != 0) {
  286. u32 sport, dport;
  287. char *src_s;
  288. char *dst_s, *sport_s, *dport_s;
  289. struct in6_addr src3, dst3;
  290. line += 5;
  291. src_s = line;
  292. dst_s = sport_s = dport_s = NULL;
  293. while (1) {
  294. if (line > end - 2) {
  295. goto missing;
  296. }
  297. else if (*line == '\r') {
  298. *line = 0;
  299. line++;
  300. if (*line++ != '\n')
  301. goto bad_header;
  302. break;
  303. }
  304. if (*line == ' ') {
  305. *line = 0;
  306. if (!dst_s)
  307. dst_s = line + 1;
  308. else if (!sport_s)
  309. sport_s = line + 1;
  310. else if (!dport_s)
  311. dport_s = line + 1;
  312. }
  313. line++;
  314. }
  315. if (!dst_s || !sport_s || !dport_s)
  316. goto bad_header;
  317. sport = read_uint((const char **)&sport_s,dport_s - 1);
  318. if (*sport_s != 0)
  319. goto bad_header;
  320. dport = read_uint((const char **)&dport_s,line - 2);
  321. if (*dport_s != 0)
  322. goto bad_header;
  323. if (inet_pton(AF_INET6, src_s, (void *)&src3) != 1)
  324. goto bad_header;
  325. if (inet_pton(AF_INET6, dst_s, (void *)&dst3) != 1)
  326. goto bad_header;
  327. /* update the session's addresses and mark them set */
  328. ((struct sockaddr_in6 *)&conn->addr.from)->sin6_family = AF_INET6;
  329. memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, &src3, sizeof(struct in6_addr));
  330. ((struct sockaddr_in6 *)&conn->addr.from)->sin6_port = htons(sport);
  331. ((struct sockaddr_in6 *)&conn->addr.to)->sin6_family = AF_INET6;
  332. memcpy(&((struct sockaddr_in6 *)&conn->addr.to)->sin6_addr, &dst3, sizeof(struct in6_addr));
  333. ((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = htons(dport);
  334. conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
  335. }
  336. else if (memcmp(line, "UNKNOWN\r\n", 9) == 0) {
  337. /* This can be a UNIX socket forwarded by an haproxy upstream */
  338. line += 9;
  339. }
  340. else {
  341. /* The protocol does not match something known (TCP4/TCP6/UNKNOWN) */
  342. conn->err_code = CO_ER_PRX_BAD_PROTO;
  343. goto fail;
  344. }
  345. trash.len = line - trash.str;
  346. goto eat_header;
  347. not_v1:
  348. /* try PPv2 */
  349. if (trash.len < PP2_HEADER_LEN)
  350. goto missing;
  351. hdr_v2 = (struct proxy_hdr_v2 *)trash.str;
  352. if (memcmp(hdr_v2->sig, v2sig, PP2_SIGNATURE_LEN) != 0 ||
  353. (hdr_v2->ver_cmd & PP2_VERSION_MASK) != PP2_VERSION) {
  354. conn->err_code = CO_ER_PRX_NOT_HDR;
  355. goto fail;
  356. }
  357. if (trash.len < PP2_HEADER_LEN + ntohs(hdr_v2->len))
  358. goto missing;
  359. switch (hdr_v2->ver_cmd & PP2_CMD_MASK) {
  360. case 0x01: /* PROXY command */
  361. switch (hdr_v2->fam) {
  362. case 0x11: /* TCPv4 */
  363. ((struct sockaddr_in *)&conn->addr.from)->sin_family = AF_INET;
  364. ((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = hdr_v2->addr.ip4.src_addr;
  365. ((struct sockaddr_in *)&conn->addr.from)->sin_port = hdr_v2->addr.ip4.src_port;
  366. ((struct sockaddr_in *)&conn->addr.to)->sin_family = AF_INET;
  367. ((struct sockaddr_in *)&conn->addr.to)->sin_addr.s_addr = hdr_v2->addr.ip4.dst_addr;
  368. ((struct sockaddr_in *)&conn->addr.to)->sin_port = hdr_v2->addr.ip4.dst_port;
  369. conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
  370. break;
  371. case 0x21: /* TCPv6 */
  372. ((struct sockaddr_in6 *)&conn->addr.from)->sin6_family = AF_INET6;
  373. memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, hdr_v2->addr.ip6.src_addr, 16);
  374. ((struct sockaddr_in6 *)&conn->addr.from)->sin6_port = hdr_v2->addr.ip6.src_port;
  375. ((struct sockaddr_in6 *)&conn->addr.to)->sin6_family = AF_INET6;
  376. memcpy(&((struct sockaddr_in6 *)&conn->addr.to)->sin6_addr, hdr_v2->addr.ip6.dst_addr, 16);
  377. ((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = hdr_v2->addr.ip6.dst_port;
  378. conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
  379. break;
  380. }
  381. /* unsupported protocol, keep local connection address */
  382. break;
  383. case 0x00: /* LOCAL command */
  384. /* keep local connection address for LOCAL */
  385. break;
  386. default:
  387. goto bad_header; /* not a supported command */
  388. }
  389. trash.len = PP2_HEADER_LEN + ntohs(hdr_v2->len);
  390. goto eat_header;
  391. eat_header:
  392. /* remove the PROXY line from the request. For this we re-read the
  393. * exact line at once. If we don't get the exact same result, we
  394. * fail.
  395. */
  396. do {
  397. int len2 = recv(conn->t.sock.fd, trash.str, trash.len, 0);
  398. if (len2 < 0 && errno == EINTR)
  399. continue;
  400. if (len2 != trash.len)
  401. goto recv_abort;
  402. } while (0);
  403. conn->flags &= ~flag;
  404. return 1;
  405. missing:
  406. /* Missing data. Since we're using MSG_PEEK, we can only poll again if
  407. * we have not read anything. Otherwise we need to fail because we won't
  408. * be able to poll anymore.
  409. */
  410. conn->err_code = CO_ER_PRX_TRUNCATED;
  411. goto fail;
  412. bad_header:
  413. /* This is not a valid proxy protocol header */
  414. conn->err_code = CO_ER_PRX_BAD_HDR;
  415. goto fail;
  416. recv_abort:
  417. conn->err_code = CO_ER_PRX_ABORT;
  418. conn->flags |= CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH;
  419. goto fail;
  420. fail:
  421. __conn_sock_stop_both(conn);
  422. conn->flags |= CO_FL_ERROR;
  423. return 0;
  424. }
  425. int make_proxy_line(char *buf, int buf_len, struct server *srv, struct connection *remote)
  426. {
  427. int ret = 0;
  428. if (srv && (srv->pp_opts & SRV_PP_V2)) {
  429. ret = make_proxy_line_v2(buf, buf_len, srv, remote);
  430. }
  431. else {
  432. if (remote)
  433. ret = make_proxy_line_v1(buf, buf_len, &remote->addr.from, &remote->addr.to);
  434. else
  435. ret = make_proxy_line_v1(buf, buf_len, NULL, NULL);
  436. }
  437. return ret;
  438. }
  439. /* Makes a PROXY protocol line from the two addresses. The output is sent to
  440. * buffer <buf> for a maximum size of <buf_len> (including the trailing zero).
  441. * It returns the number of bytes composing this line (including the trailing
  442. * LF), or zero in case of failure (eg: not enough space). It supports TCP4,
  443. * TCP6 and "UNKNOWN" formats. If any of <src> or <dst> is null, UNKNOWN is
  444. * emitted as well.
  445. */
  446. int make_proxy_line_v1(char *buf, int buf_len, struct sockaddr_storage *src, struct sockaddr_storage *dst)
  447. {
  448. int ret = 0;
  449. if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET) {
  450. ret = snprintf(buf + ret, buf_len - ret, "PROXY TCP4 ");
  451. if (ret >= buf_len)
  452. return 0;
  453. /* IPv4 src */
  454. if (!inet_ntop(src->ss_family, &((struct sockaddr_in *)src)->sin_addr, buf + ret, buf_len - ret))
  455. return 0;
  456. ret += strlen(buf + ret);
  457. if (ret >= buf_len)
  458. return 0;
  459. buf[ret++] = ' ';
  460. /* IPv4 dst */
  461. if (!inet_ntop(dst->ss_family, &((struct sockaddr_in *)dst)->sin_addr, buf + ret, buf_len - ret))
  462. return 0;
  463. ret += strlen(buf + ret);
  464. if (ret >= buf_len)
  465. return 0;
  466. /* source and destination ports */
  467. ret += snprintf(buf + ret, buf_len - ret, " %u %u\r\n",
  468. ntohs(((struct sockaddr_in *)src)->sin_port),
  469. ntohs(((struct sockaddr_in *)dst)->sin_port));
  470. if (ret >= buf_len)
  471. return 0;
  472. }
  473. else if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET6) {
  474. ret = snprintf(buf + ret, buf_len - ret, "PROXY TCP6 ");
  475. if (ret >= buf_len)
  476. return 0;
  477. /* IPv6 src */
  478. if (!inet_ntop(src->ss_family, &((struct sockaddr_in6 *)src)->sin6_addr, buf + ret, buf_len - ret))
  479. return 0;
  480. ret += strlen(buf + ret);
  481. if (ret >= buf_len)
  482. return 0;
  483. buf[ret++] = ' ';
  484. /* IPv6 dst */
  485. if (!inet_ntop(dst->ss_family, &((struct sockaddr_in6 *)dst)->sin6_addr, buf + ret, buf_len - ret))
  486. return 0;
  487. ret += strlen(buf + ret);
  488. if (ret >= buf_len)
  489. return 0;
  490. /* source and destination ports */
  491. ret += snprintf(buf + ret, buf_len - ret, " %u %u\r\n",
  492. ntohs(((struct sockaddr_in6 *)src)->sin6_port),
  493. ntohs(((struct sockaddr_in6 *)dst)->sin6_port));
  494. if (ret >= buf_len)
  495. return 0;
  496. }
  497. else {
  498. /* unknown family combination */
  499. ret = snprintf(buf, buf_len, "PROXY UNKNOWN\r\n");
  500. if (ret >= buf_len)
  501. return 0;
  502. }
  503. return ret;
  504. }
  505. #ifdef USE_OPENSSL
  506. static int make_tlv(char *dest, int dest_len, char type, uint16_t length, char *value)
  507. {
  508. struct tlv *tlv;
  509. if (!dest || (length + sizeof(*tlv) > dest_len))
  510. return 0;
  511. tlv = (struct tlv *)dest;
  512. tlv->type = type;
  513. tlv->length_hi = length >> 8;
  514. tlv->length_lo = length & 0x00ff;
  515. memcpy(tlv->value, value, length);
  516. return length + sizeof(*tlv);
  517. }
  518. #endif
  519. int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connection *remote)
  520. {
  521. const char pp2_signature[] = PP2_SIGNATURE;
  522. int ret = 0;
  523. struct proxy_hdr_v2 *hdr = (struct proxy_hdr_v2 *)buf;
  524. struct sockaddr_storage null_addr = {0};
  525. struct sockaddr_storage *src = &null_addr;
  526. struct sockaddr_storage *dst = &null_addr;
  527. #ifdef USE_OPENSSL
  528. int tlv_len = 0;
  529. char *value = NULL;
  530. struct tlv_ssl *tlv;
  531. int ssl_tlv_len = 0;
  532. #endif
  533. if (buf_len < PP2_HEADER_LEN)
  534. return 0;
  535. memcpy(hdr->sig, pp2_signature, PP2_SIGNATURE_LEN);
  536. if (remote) {
  537. src = &remote->addr.from;
  538. dst = &remote->addr.to;
  539. }
  540. if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET) {
  541. if (buf_len < PP2_HDR_LEN_INET)
  542. return 0;
  543. hdr->ver_cmd = PP2_VERSION | PP2_CMD_PROXY;
  544. hdr->fam = PP2_FAM_INET | PP2_TRANS_STREAM;
  545. hdr->addr.ip4.src_addr = ((struct sockaddr_in *)src)->sin_addr.s_addr;
  546. hdr->addr.ip4.dst_addr = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
  547. hdr->addr.ip4.src_port = ((struct sockaddr_in *)src)->sin_port;
  548. hdr->addr.ip4.dst_port = ((struct sockaddr_in *)dst)->sin_port;
  549. ret = PP2_HDR_LEN_INET;
  550. }
  551. else if (src && dst && src->ss_family == dst->ss_family && src->ss_family == AF_INET6) {
  552. if (buf_len < PP2_HDR_LEN_INET6)
  553. return 0;
  554. hdr->ver_cmd = PP2_VERSION | PP2_CMD_PROXY;
  555. hdr->fam = PP2_FAM_INET6 | PP2_TRANS_STREAM;
  556. memcpy(hdr->addr.ip6.src_addr, &((struct sockaddr_in6 *)src)->sin6_addr, 16);
  557. memcpy(hdr->addr.ip6.dst_addr, &((struct sockaddr_in6 *)dst)->sin6_addr, 16);
  558. hdr->addr.ip6.src_port = ((struct sockaddr_in6 *)src)->sin6_port;
  559. hdr->addr.ip6.dst_port = ((struct sockaddr_in6 *)dst)->sin6_port;
  560. ret = PP2_HDR_LEN_INET6;
  561. }
  562. else {
  563. if (buf_len < PP2_HDR_LEN_UNSPEC)
  564. return 0;
  565. hdr->ver_cmd = PP2_VERSION | PP2_CMD_LOCAL;
  566. hdr->fam = PP2_FAM_UNSPEC | PP2_TRANS_UNSPEC;
  567. ret = PP2_HDR_LEN_UNSPEC;
  568. }
  569. #ifdef USE_OPENSSL
  570. if (srv->pp_opts & SRV_PP_V2_SSL) {
  571. if ((buf_len - ret) < sizeof(struct tlv_ssl))
  572. return 0;
  573. tlv = (struct tlv_ssl *)&buf[ret];
  574. memset(tlv, 0, sizeof(struct tlv_ssl));
  575. ssl_tlv_len += sizeof(struct tlv_ssl);
  576. tlv->tlv.type = PP2_TYPE_SSL;
  577. if (ssl_sock_is_ssl(remote)) {
  578. tlv->client |= PP2_CLIENT_SSL;
  579. value = ssl_sock_get_version(remote);
  580. if (value) {
  581. tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len-ret-ssl_tlv_len), PP2_TYPE_SSL_VERSION, strlen(value), value);
  582. ssl_tlv_len += tlv_len;
  583. }
  584. if (ssl_sock_get_cert_used(remote)) {
  585. tlv->client |= PP2_CLIENT_CERT;
  586. tlv->verify = htonl(ssl_sock_get_verify_result(remote));
  587. }
  588. if (srv->pp_opts & SRV_PP_V2_SSL_CN) {
  589. value = ssl_sock_get_common_name(remote);
  590. if (value) {
  591. tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, strlen(value), value);
  592. ssl_tlv_len += tlv_len;
  593. }
  594. }
  595. }
  596. tlv->tlv.length_hi = (uint16_t)(ssl_tlv_len - sizeof(struct tlv)) >> 8;
  597. tlv->tlv.length_lo = (uint16_t)(ssl_tlv_len - sizeof(struct tlv)) & 0x00ff;
  598. ret += ssl_tlv_len;
  599. }
  600. #endif
  601. hdr->len = htons((uint16_t)(ret - PP2_HEADER_LEN));
  602. return ret;
  603. }