You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
6.9 KiB

  1. From 4f889006269e4d3f802de46f280ed198a15e3a69 Mon Sep 17 00:00:00 2001
  2. From: Willy Tarreau <w@1wt.eu>
  3. Date: Wed, 13 May 2015 11:23:01 +0200
  4. Subject: [PATCH 4/8] CLEANUP: checks: fix double usage of cur / current_step
  5. in tcp-checks
  6. This cleanup is a preliminary requirement to the upcoming fixes for
  7. the bug that affect tcp-check's improper use of lists. It will have
  8. to be backported to 1.5 though it will not easily apply.
  9. There are two variables pointing to the current rule within the loop,
  10. and either one or the other is used depending on the code blocks,
  11. making it much harder to apply checks to fix the list walking bug.
  12. So first get rid of "cur" and only focus on current_step.
  13. (cherry picked from commit ce8c42a37a44a1e0cb94e81abb7cc2baf3d0ef80)
  14. [wt: 1.5 doesn't have comments so this patch differs significantly
  15. from 1.6, but it's needed for the next batch of fixes]
  16. ---
  17. src/checks.c | 57 ++++++++++++++++++++++++++++-----------------------------
  18. 1 file changed, 28 insertions(+), 29 deletions(-)
  19. diff --git a/src/checks.c b/src/checks.c
  20. index 8b53f97..cfdfe8c 100644
  21. --- a/src/checks.c
  22. +++ b/src/checks.c
  23. @@ -1859,7 +1859,7 @@ static int tcpcheck_get_step_id(struct server *s)
  24. static void tcpcheck_main(struct connection *conn)
  25. {
  26. char *contentptr;
  27. - struct tcpcheck_rule *cur, *next;
  28. + struct tcpcheck_rule *next;
  29. int done = 0, ret = 0;
  30. struct check *check = conn->owner;
  31. struct server *s = check->server;
  32. @@ -1916,15 +1916,11 @@ static void tcpcheck_main(struct connection *conn)
  33. check->bo->o = 0;
  34. check->bi->p = check->bi->data;
  35. check->bi->i = 0;
  36. - cur = check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list);
  37. + check->current_step = LIST_ELEM(head->n, struct tcpcheck_rule *, list);
  38. t->expire = tick_add(now_ms, MS_TO_TICKS(check->inter));
  39. if (s->proxy->timeout.check)
  40. t->expire = tick_add_ifset(now_ms, s->proxy->timeout.check);
  41. }
  42. - /* keep on processing step */
  43. - else {
  44. - cur = check->current_step;
  45. - }
  46. /* It's only the rules which will enable send/recv */
  47. __conn_data_stop_both(conn);
  48. @@ -1934,7 +1930,7 @@ static void tcpcheck_main(struct connection *conn)
  49. * or if we're about to send a string that does not fit in the remaining space.
  50. */
  51. if (check->bo->o &&
  52. - (&cur->list == head ||
  53. + (&check->current_step->list == head ||
  54. check->current_step->action != TCPCHK_ACT_SEND ||
  55. check->current_step->string_len >= buffer_total_space(check->bo))) {
  56. @@ -1949,14 +1945,17 @@ static void tcpcheck_main(struct connection *conn)
  57. }
  58. /* did we reach the end ? If so, let's check that everything was sent */
  59. - if (&cur->list == head) {
  60. + if (&check->current_step->list == head) {
  61. if (check->bo->o)
  62. goto out_need_io;
  63. break;
  64. }
  65. - /* have 'next' point to the next rule or NULL if we're on the last one */
  66. - next = (struct tcpcheck_rule *)cur->list.n;
  67. + /* have 'next' point to the next rule or NULL if we're on the
  68. + * last one, connect() needs this.
  69. + */
  70. + next = (struct tcpcheck_rule *)check->current_step->list.n;
  71. +
  72. if (&next->list == head)
  73. next = NULL;
  74. @@ -2058,8 +2057,7 @@ static void tcpcheck_main(struct connection *conn)
  75. }
  76. /* allow next rule */
  77. - cur = (struct tcpcheck_rule *)cur->list.n;
  78. - check->current_step = cur;
  79. + check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
  80. /* don't do anything until the connection is established */
  81. if (!(conn->flags & CO_FL_CONNECTED)) {
  82. @@ -2113,8 +2111,7 @@ static void tcpcheck_main(struct connection *conn)
  83. *check->bo->p = '\0'; /* to make gdb output easier to read */
  84. /* go to next rule and try to send */
  85. - cur = (struct tcpcheck_rule *)cur->list.n;
  86. - check->current_step = cur;
  87. + check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
  88. } /* end 'send' */
  89. else if (check->current_step->action == TCPCHK_ACT_EXPECT) {
  90. if (unlikely(check->result == CHK_RES_FAILED))
  91. @@ -2167,14 +2164,14 @@ static void tcpcheck_main(struct connection *conn)
  92. goto out_end_tcpcheck;
  93. }
  94. - if (!done && (cur->string != NULL) && (check->bi->i < cur->string_len) )
  95. + if (!done && (check->current_step->string != NULL) && (check->bi->i < check->current_step->string_len) )
  96. continue; /* try to read more */
  97. tcpcheck_expect:
  98. - if (cur->string != NULL)
  99. - ret = my_memmem(contentptr, check->bi->i, cur->string, cur->string_len) != NULL;
  100. - else if (cur->expect_regex != NULL)
  101. - ret = regex_exec(cur->expect_regex, contentptr);
  102. + if (check->current_step->string != NULL)
  103. + ret = my_memmem(contentptr, check->bi->i, check->current_step->string, check->current_step->string_len) != NULL;
  104. + else if (check->current_step->expect_regex != NULL)
  105. + ret = regex_exec(check->current_step->expect_regex, contentptr);
  106. if (!ret && !done)
  107. continue; /* try to read more */
  108. @@ -2182,11 +2179,11 @@ static void tcpcheck_main(struct connection *conn)
  109. /* matched */
  110. if (ret) {
  111. /* matched but we did not want to => ERROR */
  112. - if (cur->inverse) {
  113. + if (check->current_step->inverse) {
  114. /* we were looking for a string */
  115. - if (cur->string != NULL) {
  116. + if (check->current_step->string != NULL) {
  117. chunk_printf(&trash, "TCPCHK matched unwanted content '%s' at step %d",
  118. - cur->string, tcpcheck_get_step_id(s));
  119. + check->current_step->string, tcpcheck_get_step_id(s));
  120. }
  121. else {
  122. /* we were looking for a regex */
  123. @@ -2198,8 +2195,9 @@ static void tcpcheck_main(struct connection *conn)
  124. }
  125. /* matched and was supposed to => OK, next step */
  126. else {
  127. - cur = (struct tcpcheck_rule*)cur->list.n;
  128. - check->current_step = cur;
  129. + /* allow next rule */
  130. + check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
  131. +
  132. if (check->current_step->action == TCPCHK_ACT_EXPECT)
  133. goto tcpcheck_expect;
  134. __conn_data_stop_recv(conn);
  135. @@ -2208,9 +2206,10 @@ static void tcpcheck_main(struct connection *conn)
  136. else {
  137. /* not matched */
  138. /* not matched and was not supposed to => OK, next step */
  139. - if (cur->inverse) {
  140. - cur = (struct tcpcheck_rule*)cur->list.n;
  141. - check->current_step = cur;
  142. + if (check->current_step->inverse) {
  143. + /* allow next rule */
  144. + check->current_step = (struct tcpcheck_rule *)check->current_step->list.n;
  145. +
  146. if (check->current_step->action == TCPCHK_ACT_EXPECT)
  147. goto tcpcheck_expect;
  148. __conn_data_stop_recv(conn);
  149. @@ -2218,9 +2217,9 @@ static void tcpcheck_main(struct connection *conn)
  150. /* not matched but was supposed to => ERROR */
  151. else {
  152. /* we were looking for a string */
  153. - if (cur->string != NULL) {
  154. + if (check->current_step->string != NULL) {
  155. chunk_printf(&trash, "TCPCHK did not match content '%s' at step %d",
  156. - cur->string, tcpcheck_get_step_id(s));
  157. + check->current_step->string, tcpcheck_get_step_id(s));
  158. }
  159. else {
  160. /* we were looking for a regex */
  161. --
  162. 2.0.5