From guillaume at varnish-software.com Mon Aug 6 02:01:13 2018 From: guillaume at varnish-software.com (Guillaume Quintard) Date: Mon, 6 Aug 2018 02:01:13 +0000 (UTC) Subject: [master] 38994b559 [varnishtest] generate the decoding tables Message-ID: <20180806020113.BF1D36238D@lists.varnish-cache.org> commit 38994b55913828e16d08afd1b22baa157a1a67f8 Author: Guillaume Quintard Date: Sun Aug 5 09:55:08 2018 -0700 [varnishtest] generate the decoding tables diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 0deef9cfb..200f43394 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -76,7 +76,8 @@ EXTRA_DIST = $(top_srcdir)/bin/varnishtest/tests/*.vtc \ $(top_srcdir)/bin/varnishtest/tests/README \ $(top_srcdir)/bin/varnishtest/gensequences \ $(top_srcdir)/bin/varnishtest/sequences \ - $(top_srcdir)/bin/varnishtest/teken.3 + $(top_srcdir)/bin/varnishtest/teken.3 \ + huffman_gen.py teken.c: teken_state.h @@ -84,4 +85,8 @@ teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences awk -f $(srcdir)/gensequences $(srcdir)/sequences \ > $(builddir)/teken_state.h +vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h + $(srcdir)/huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ + mv $@_ $@ + CLEANFILES = $(builddir)/teken_state.h diff --git a/bin/varnishtest/huffman_gen.py b/bin/varnishtest/huffman_gen.py new file mode 100755 index 000000000..1486bd41d --- /dev/null +++ b/bin/varnishtest/huffman_gen.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +import re +import sys + +#HPH(0x30, 0x00000000, 5) +regex = re.compile("^HPH\((.{4}), (.{10}), +(.{1,3})\)") + +if len(sys.argv) != 2: + print("{} takes one and only one argument".format(sys.argv[0])) + sys.exit(2) + +class sym: + def __init__(self, bigval, bigvall, chr = 0, esc = None): + self.vall = bigvall % 8 if bigvall % 8 else 8 + self.val = bigval & ((1 << self.vall) - 1) + self.pfx = (bigval >> self.vall)# & 0xff + self.chr = chr + self.esc = esc + +tbls = {} +msl = {} # max sym length + +f = open(sys.argv[1]) +for l in f: + grp = 1 + match = regex.match(l) + if not match: + continue + + chr = int(match.group(grp), 16) + grp += 1 + + val = int(match.group(grp), 16) + grp += 1 + + vall = int(match.group(grp)) + + s = sym(val, vall, chr) + if s.pfx not in tbls: + tbls[s.pfx] = {} + + if (s.val in tbls[s.pfx]): + assert(tbls[s.pfx][s.val].e) + tbls[s.pfx][s.val] = s + + # add the escape entry in the "previous" table + if s.pfx: + pp = s.pfx >> 8 + pv = s.pfx & 0xff + if pp not in tbls: + tbls[pp] = {} + tbls[pp][pv] = sym(pv, 8, 0, "&tbl_{:x}".format(s.pfx)) +f.close() + +# add the EOS case +s = sym(63, 6, 0) +tbls[0xffffff][63] = s + +print('''/* NB: This file is machine generated, DO NOT EDIT! + * edit bin/varnishtest/huffman_input instead + */ + +struct stbl; + +struct ssym { + uint8_t csm; /* bits consumed */ + uint8_t chr; /* character */ + struct stbl *nxt; /* next table */ +}; + +struct stbl { + int msk; + struct ssym *syms; +}; +''') + +for pfx in sorted(tbls.keys(), reverse=True): + msl = max([ x.vall for x in tbls[pfx].values() ]) + for s in tbls[pfx].values(): + s.val = s.val << (msl - s.vall) + + tbl = sorted(tbls[pfx].values(), key= lambda x: x.val) + print("\nstatic struct ssym sym_{:x}_array[] = {{".format(pfx)) + for s in tbl: + for j in range(2 ** (msl - s.vall)): + print(" {} {{{}, {:3d}, {}}},".format( + " "*13 if j else "/* idx {:3d} */".format(s.val + j), + s.vall, s.chr % 256, + s.esc if s.esc else "NULL")) + print('''}}; + +static struct stbl tbl_{:x} = {{ + {}, + sym_{:x}_array +}};'''.format(pfx, msl, pfx)) diff --git a/bin/varnishtest/huffman_input b/bin/varnishtest/huffman_input new file mode 100644 index 000000000..bfde068cd --- /dev/null +++ b/bin/varnishtest/huffman_input @@ -0,0 +1,257 @@ + ( 0) |11111111|11000 1ff8 [13] + ( 1) |11111111|11111111|1011000 7fffd8 [23] + ( 2) |11111111|11111111|11111110|0010 fffffe2 [28] + ( 3) |11111111|11111111|11111110|0011 fffffe3 [28] + ( 4) |11111111|11111111|11111110|0100 fffffe4 [28] + ( 5) |11111111|11111111|11111110|0101 fffffe5 [28] + ( 6) |11111111|11111111|11111110|0110 fffffe6 [28] + ( 7) |11111111|11111111|11111110|0111 fffffe7 [28] + ( 8) |11111111|11111111|11111110|1000 fffffe8 [28] + ( 9) |11111111|11111111|11101010 ffffea [24] + ( 10) |11111111|11111111|11111111|111100 3ffffffc [30] + ( 11) |11111111|11111111|11111110|1001 fffffe9 [28] + ( 12) |11111111|11111111|11111110|1010 fffffea [28] + ( 13) |11111111|11111111|11111111|111101 3ffffffd [30] + ( 14) |11111111|11111111|11111110|1011 fffffeb [28] + ( 15) |11111111|11111111|11111110|1100 fffffec [28] + ( 16) |11111111|11111111|11111110|1101 fffffed [28] + ( 17) |11111111|11111111|11111110|1110 fffffee [28] + ( 18) |11111111|11111111|11111110|1111 fffffef [28] + ( 19) |11111111|11111111|11111111|0000 ffffff0 [28] + ( 20) |11111111|11111111|11111111|0001 ffffff1 [28] + ( 21) |11111111|11111111|11111111|0010 ffffff2 [28] + ( 22) |11111111|11111111|11111111|111110 3ffffffe [30] + ( 23) |11111111|11111111|11111111|0011 ffffff3 [28] + ( 24) |11111111|11111111|11111111|0100 ffffff4 [28] + ( 25) |11111111|11111111|11111111|0101 ffffff5 [28] + ( 26) |11111111|11111111|11111111|0110 ffffff6 [28] + ( 27) |11111111|11111111|11111111|0111 ffffff7 [28] + ( 28) |11111111|11111111|11111111|1000 ffffff8 [28] + ( 29) |11111111|11111111|11111111|1001 ffffff9 [28] + ( 30) |11111111|11111111|11111111|1010 ffffffa [28] + ( 31) |11111111|11111111|11111111|1011 ffffffb [28] + ' ' ( 32) |010100 14 [ 6] + '!' ( 33) |11111110|00 3f8 [10] + '"' ( 34) |11111110|01 3f9 [10] + '#' ( 35) |11111111|1010 ffa [12] + '$' ( 36) |11111111|11001 1ff9 [13] + '%' ( 37) |010101 15 [ 6] + '&' ( 38) |11111000 f8 [ 8] + ''' ( 39) |11111111|010 7fa [11] + '(' ( 40) |11111110|10 3fa [10] + ')' ( 41) |11111110|11 3fb [10] + '*' ( 42) |11111001 f9 [ 8] + '+' ( 43) |11111111|011 7fb [11] + ',' ( 44) |11111010 fa [ 8] + '-' ( 45) |010110 16 [ 6] + '.' ( 46) |010111 17 [ 6] + '/' ( 47) |011000 18 [ 6] + '0' ( 48) |00000 0 [ 5] + '1' ( 49) |00001 1 [ 5] + '2' ( 50) |00010 2 [ 5] + '3' ( 51) |011001 19 [ 6] + '4' ( 52) |011010 1a [ 6] + '5' ( 53) |011011 1b [ 6] + '6' ( 54) |011100 1c [ 6] + '7' ( 55) |011101 1d [ 6] + '8' ( 56) |011110 1e [ 6] + '9' ( 57) |011111 1f [ 6] + ':' ( 58) |1011100 5c [ 7] + ';' ( 59) |11111011 fb [ 8] + '<' ( 60) |11111111|1111100 7ffc [15] + '=' ( 61) |100000 20 [ 6] + '>' ( 62) |11111111|1011 ffb [12] + '?' ( 63) |11111111|00 3fc [10] + '@' ( 64) |11111111|11010 1ffa [13] + 'A' ( 65) |100001 21 [ 6] + 'B' ( 66) |1011101 5d [ 7] + 'C' ( 67) |1011110 5e [ 7] + 'D' ( 68) |1011111 5f [ 7] + 'E' ( 69) |1100000 60 [ 7] + 'F' ( 70) |1100001 61 [ 7] + 'G' ( 71) |1100010 62 [ 7] + 'H' ( 72) |1100011 63 [ 7] + 'I' ( 73) |1100100 64 [ 7] + 'J' ( 74) |1100101 65 [ 7] + 'K' ( 75) |1100110 66 [ 7] + 'L' ( 76) |1100111 67 [ 7] + 'M' ( 77) |1101000 68 [ 7] + 'N' ( 78) |1101001 69 [ 7] + 'O' ( 79) |1101010 6a [ 7] + 'P' ( 80) |1101011 6b [ 7] + 'Q' ( 81) |1101100 6c [ 7] + 'R' ( 82) |1101101 6d [ 7] + 'S' ( 83) |1101110 6e [ 7] + 'T' ( 84) |1101111 6f [ 7] + 'U' ( 85) |1110000 70 [ 7] + 'V' ( 86) |1110001 71 [ 7] + 'W' ( 87) |1110010 72 [ 7] + 'X' ( 88) |11111100 fc [ 8] + 'Y' ( 89) |1110011 73 [ 7] + 'Z' ( 90) |11111101 fd [ 8] + '[' ( 91) |11111111|11011 1ffb [13] + '\' ( 92) |11111111|11111110|000 7fff0 [19] + ']' ( 93) |11111111|11100 1ffc [13] + '^' ( 94) |11111111|111100 3ffc [14] + '_' ( 95) |100010 22 [ 6] + '`' ( 96) |11111111|1111101 7ffd [15] + 'a' ( 97) |00011 3 [ 5] + 'b' ( 98) |100011 23 [ 6] + 'c' ( 99) |00100 4 [ 5] + 'd' (100) |100100 24 [ 6] + 'e' (101) |00101 5 [ 5] + 'f' (102) |100101 25 [ 6] + 'g' (103) |100110 26 [ 6] + 'h' (104) |100111 27 [ 6] + 'i' (105) |00110 6 [ 5] + 'j' (106) |1110100 74 [ 7] + 'k' (107) |1110101 75 [ 7] + 'l' (108) |101000 28 [ 6] + 'm' (109) |101001 29 [ 6] + 'n' (110) |101010 2a [ 6] + 'o' (111) |00111 7 [ 5] + 'p' (112) |101011 2b [ 6] + 'q' (113) |1110110 76 [ 7] + 'r' (114) |101100 2c [ 6] + 's' (115) |01000 8 [ 5] + 't' (116) |01001 9 [ 5] + 'u' (117) |101101 2d [ 6] + 'v' (118) |1110111 77 [ 7] + 'w' (119) |1111000 78 [ 7] + 'x' (120) |1111001 79 [ 7] + 'y' (121) |1111010 7a [ 7] + 'z' (122) |1111011 7b [ 7] + '{' (123) |11111111|1111110 7ffe [15] + '|' (124) |11111111|100 7fc [11] + '}' (125) |11111111|111101 3ffd [14] + '~' (126) |11111111|11101 1ffd [13] + (127) |11111111|11111111|11111111|1100 ffffffc [28] + (128) |11111111|11111110|0110 fffe6 [20] + (129) |11111111|11111111|010010 3fffd2 [22] + (130) |11111111|11111110|0111 fffe7 [20] + (131) |11111111|11111110|1000 fffe8 [20] + (132) |11111111|11111111|010011 3fffd3 [22] + (133) |11111111|11111111|010100 3fffd4 [22] + (134) |11111111|11111111|010101 3fffd5 [22] + (135) |11111111|11111111|1011001 7fffd9 [23] + (136) |11111111|11111111|010110 3fffd6 [22] + (137) |11111111|11111111|1011010 7fffda [23] + (138) |11111111|11111111|1011011 7fffdb [23] + (139) |11111111|11111111|1011100 7fffdc [23] + (140) |11111111|11111111|1011101 7fffdd [23] + (141) |11111111|11111111|1011110 7fffde [23] + (142) |11111111|11111111|11101011 ffffeb [24] + (143) |11111111|11111111|1011111 7fffdf [23] + (144) |11111111|11111111|11101100 ffffec [24] + (145) |11111111|11111111|11101101 ffffed [24] + (146) |11111111|11111111|010111 3fffd7 [22] + (147) |11111111|11111111|1100000 7fffe0 [23] + (148) |11111111|11111111|11101110 ffffee [24] + (149) |11111111|11111111|1100001 7fffe1 [23] + (150) |11111111|11111111|1100010 7fffe2 [23] + (151) |11111111|11111111|1100011 7fffe3 [23] + (152) |11111111|11111111|1100100 7fffe4 [23] + (153) |11111111|11111110|11100 1fffdc [21] + (154) |11111111|11111111|011000 3fffd8 [22] + (155) |11111111|11111111|1100101 7fffe5 [23] + (156) |11111111|11111111|011001 3fffd9 [22] + (157) |11111111|11111111|1100110 7fffe6 [23] + (158) |11111111|11111111|1100111 7fffe7 [23] + (159) |11111111|11111111|11101111 ffffef [24] + (160) |11111111|11111111|011010 3fffda [22] + (161) |11111111|11111110|11101 1fffdd [21] + (162) |11111111|11111110|1001 fffe9 [20] + (163) |11111111|11111111|011011 3fffdb [22] + (164) |11111111|11111111|011100 3fffdc [22] + (165) |11111111|11111111|1101000 7fffe8 [23] + (166) |11111111|11111111|1101001 7fffe9 [23] + (167) |11111111|11111110|11110 1fffde [21] + (168) |11111111|11111111|1101010 7fffea [23] + (169) |11111111|11111111|011101 3fffdd [22] + (170) |11111111|11111111|011110 3fffde [22] + (171) |11111111|11111111|11110000 fffff0 [24] + (172) |11111111|11111110|11111 1fffdf [21] + (173) |11111111|11111111|011111 3fffdf [22] + (174) |11111111|11111111|1101011 7fffeb [23] + (175) |11111111|11111111|1101100 7fffec [23] + (176) |11111111|11111111|00000 1fffe0 [21] + (177) |11111111|11111111|00001 1fffe1 [21] + (178) |11111111|11111111|100000 3fffe0 [22] + (179) |11111111|11111111|00010 1fffe2 [21] + (180) |11111111|11111111|1101101 7fffed [23] + (181) |11111111|11111111|100001 3fffe1 [22] + (182) |11111111|11111111|1101110 7fffee [23] + (183) |11111111|11111111|1101111 7fffef [23] + (184) |11111111|11111110|1010 fffea [20] + (185) |11111111|11111111|100010 3fffe2 [22] + (186) |11111111|11111111|100011 3fffe3 [22] + (187) |11111111|11111111|100100 3fffe4 [22] + (188) |11111111|11111111|1110000 7ffff0 [23] + (189) |11111111|11111111|100101 3fffe5 [22] + (190) |11111111|11111111|100110 3fffe6 [22] + (191) |11111111|11111111|1110001 7ffff1 [23] + (192) |11111111|11111111|11111000|00 3ffffe0 [26] + (193) |11111111|11111111|11111000|01 3ffffe1 [26] + (194) |11111111|11111110|1011 fffeb [20] + (195) |11111111|11111110|001 7fff1 [19] + (196) |11111111|11111111|100111 3fffe7 [22] + (197) |11111111|11111111|1110010 7ffff2 [23] + (198) |11111111|11111111|101000 3fffe8 [22] + (199) |11111111|11111111|11110110|0 1ffffec [25] + (200) |11111111|11111111|11111000|10 3ffffe2 [26] + (201) |11111111|11111111|11111000|11 3ffffe3 [26] + (202) |11111111|11111111|11111001|00 3ffffe4 [26] + (203) |11111111|11111111|11111011|110 7ffffde [27] + (204) |11111111|11111111|11111011|111 7ffffdf [27] + (205) |11111111|11111111|11111001|01 3ffffe5 [26] + (206) |11111111|11111111|11110001 fffff1 [24] + (207) |11111111|11111111|11110110|1 1ffffed [25] + (208) |11111111|11111110|010 7fff2 [19] + (209) |11111111|11111111|00011 1fffe3 [21] + (210) |11111111|11111111|11111001|10 3ffffe6 [26] + (211) |11111111|11111111|11111100|000 7ffffe0 [27] + (212) |11111111|11111111|11111100|001 7ffffe1 [27] + (213) |11111111|11111111|11111001|11 3ffffe7 [26] + (214) |11111111|11111111|11111100|010 7ffffe2 [27] + (215) |11111111|11111111|11110010 fffff2 [24] + (216) |11111111|11111111|00100 1fffe4 [21] + (217) |11111111|11111111|00101 1fffe5 [21] + (218) |11111111|11111111|11111010|00 3ffffe8 [26] + (219) |11111111|11111111|11111010|01 3ffffe9 [26] + (220) |11111111|11111111|11111111|1101 ffffffd [28] + (221) |11111111|11111111|11111100|011 7ffffe3 [27] + (222) |11111111|11111111|11111100|100 7ffffe4 [27] + (223) |11111111|11111111|11111100|101 7ffffe5 [27] + (224) |11111111|11111110|1100 fffec [20] + (225) |11111111|11111111|11110011 fffff3 [24] + (226) |11111111|11111110|1101 fffed [20] + (227) |11111111|11111111|00110 1fffe6 [21] + (228) |11111111|11111111|101001 3fffe9 [22] + (229) |11111111|11111111|00111 1fffe7 [21] + (230) |11111111|11111111|01000 1fffe8 [21] + (231) |11111111|11111111|1110011 7ffff3 [23] + (232) |11111111|11111111|101010 3fffea [22] + (233) |11111111|11111111|101011 3fffeb [22] + (234) |11111111|11111111|11110111|0 1ffffee [25] + (235) |11111111|11111111|11110111|1 1ffffef [25] + (236) |11111111|11111111|11110100 fffff4 [24] + (237) |11111111|11111111|11110101 fffff5 [24] + (238) |11111111|11111111|11111010|10 3ffffea [26] + (239) |11111111|11111111|1110100 7ffff4 [23] + (240) |11111111|11111111|11111010|11 3ffffeb [26] + (241) |11111111|11111111|11111100|110 7ffffe6 [27] + (242) |11111111|11111111|11111011|00 3ffffec [26] + (243) |11111111|11111111|11111011|01 3ffffed [26] + (244) |11111111|11111111|11111100|111 7ffffe7 [27] + (245) |11111111|11111111|11111101|000 7ffffe8 [27] + (246) |11111111|11111111|11111101|001 7ffffe9 [27] + (247) |11111111|11111111|11111101|010 7ffffea [27] + (248) |11111111|11111111|11111101|011 7ffffeb [27] + (249) |11111111|11111111|11111111|1110 ffffffe [28] + (250) |11111111|11111111|11111101|100 7ffffec [27] + (251) |11111111|11111111|11111101|101 7ffffed [27] + (252) |11111111|11111111|11111101|110 7ffffee [27] + (253) |11111111|11111111|11111101|111 7ffffef [27] + (254) |11111111|11111111|11111110|000 7fffff0 [27] + (255) |11111111|11111111|11111011|10 3ffffee [26] + EOS (256) |11111111|11111111|11111111|111111 3fffffff [30] diff --git a/bin/varnishtest/vtc_h2_dectbl.h b/bin/varnishtest/vtc_h2_dectbl.h deleted file mode 100644 index b6402d574..000000000 --- a/bin/varnishtest/vtc_h2_dectbl.h +++ /dev/null @@ -1,1056 +0,0 @@ -struct stbl; - -struct ssym { - uint8_t csm; /* bits consumed */ - uint8_t chr; /* character */ - struct stbl *nxt; /* next table */ -}; - -struct stbl { - int msk; - struct ssym *syms; -}; - -static struct ssym byte3_pref0110_array[] = { - /* idx 0 */ {1, 199, NULL}, - /* idx 1 */ {1, 207, NULL}, -}; - -static struct stbl byte3_pref0110 = { - 1, - byte3_pref0110_array -}; - -static struct ssym byte3_pref0111_array[] = { - /* idx 0 */ {1, 234, NULL}, - /* idx 1 */ {1, 235, NULL}, -}; - -static struct stbl byte3_pref0111 = { - 1, - byte3_pref0111_array -}; - -static struct ssym byte3_pref1000_array[] = { - /* idx 0 */ {2, 192, NULL}, - /* idx 1 */ {2, 193, NULL}, - /* idx 2 */ {2, 200, NULL}, - /* idx 3 */ {2, 201, NULL}, -}; - -static struct stbl byte3_pref1000 = { - 2, - byte3_pref1000_array -}; - -static struct ssym byte3_pref1001_array[] = { - /* idx 0 */ {2, 202, NULL}, - /* idx 1 */ {2, 205, NULL}, - /* idx 2 */ {2, 210, NULL}, - /* idx 3 */ {2, 213, NULL}, -}; - -static struct stbl byte3_pref1001 = { - 2, - byte3_pref1001_array -}; - -static struct ssym byte3_pref1010_array[] = { - /* idx 0 */ {2, 218, NULL}, - /* idx 1 */ {2, 219, NULL}, - /* idx 2 */ {2, 238, NULL}, - /* idx 3 */ {2, 240, NULL}, -}; - -static struct stbl byte3_pref1010 = { - 2, - byte3_pref1010_array -}; - -static struct ssym byte3_pref1011_array[] = { - /* idx 0 */ {2, 242, NULL}, - /* idx 1 */ {2, 242, NULL}, - /* idx 2 */ {2, 243, NULL}, - /* idx 3 */ {2, 243, NULL}, - /* idx 4 */ {2, 255, NULL}, - /* idx 5 */ {2, 255, NULL}, - /* idx 6 */ {3, 203, NULL}, - /* idx 7 */ {3, 204, NULL}, -}; - -static struct stbl byte3_pref1011 = { - 3, - byte3_pref1011_array -}; - -static struct ssym byte3_pref1100_array[] = { - /* idx 0 */ {3, 211, NULL}, - /* idx 1 */ {3, 212, NULL}, - /* idx 2 */ {3, 214, NULL}, - /* idx 3 */ {3, 221, NULL}, - /* idx 4 */ {3, 222, NULL}, - /* idx 5 */ {3, 223, NULL}, - /* idx 6 */ {3, 241, NULL}, - /* idx 7 */ {3, 244, NULL}, -}; - -static struct stbl byte3_pref1100 = { - 3, - byte3_pref1100_array -}; - -static struct ssym byte3_pref1101_array[] = { - /* idx 0 */ {3, 245, NULL}, - /* idx 1 */ {3, 246, NULL}, - /* idx 2 */ {3, 247, NULL}, - /* idx 3 */ {3, 248, NULL}, - /* idx 4 */ {3, 250, NULL}, - /* idx 5 */ {3, 251, NULL}, - /* idx 6 */ {3, 252, NULL}, - /* idx 7 */ {3, 253, NULL}, -}; - -static struct stbl byte3_pref1101 = { - 3, - byte3_pref1101_array -}; - -static struct ssym byte3_pref1110_array[] = { - /* idx 0 */ {3, 254, NULL}, - /* idx 1 */ {3, 254, NULL}, - /* idx 2 */ {4, 2, NULL}, - /* idx 3 */ {4, 3, NULL}, - /* idx 4 */ {4, 4, NULL}, - /* idx 5 */ {4, 5, NULL}, - /* idx 6 */ {4, 6, NULL}, - /* idx 7 */ {4, 7, NULL}, - /* idx 8 */ {4, 8, NULL}, - /* idx 9 */ {4, 11, NULL}, - /* idx 10 */ {4, 12, NULL}, - /* idx 11 */ {4, 14, NULL}, - /* idx 12 */ {4, 15, NULL}, - /* idx 13 */ {4, 16, NULL}, - /* idx 14 */ {4, 17, NULL}, - /* idx 15 */ {4, 18, NULL}, -}; - -static struct stbl byte3_pref1110 = { - 4, - byte3_pref1110_array -}; - -static struct ssym byte3_pref1111_array[] = { - /* idx 0 */ {4, 19, NULL}, - /* idx 1 */ {4, 19, NULL}, - /* idx 2 */ {4, 19, NULL}, - /* idx 3 */ {4, 19, NULL}, - /* idx 4 */ {4, 20, NULL}, - /* idx 5 */ {4, 20, NULL}, - /* idx 6 */ {4, 20, NULL}, - /* idx 7 */ {4, 20, NULL}, - /* idx 8 */ {4, 21, NULL}, - /* idx 9 */ {4, 21, NULL}, - /* idx 10 */ {4, 21, NULL}, - /* idx 11 */ {4, 21, NULL}, - /* idx 12 */ {4, 23, NULL}, - /* idx 13 */ {4, 23, NULL}, - /* idx 14 */ {4, 23, NULL}, - /* idx 15 */ {4, 23, NULL}, - /* idx 16 */ {4, 24, NULL}, - /* idx 17 */ {4, 24, NULL}, - /* idx 18 */ {4, 24, NULL}, - /* idx 19 */ {4, 24, NULL}, - /* idx 20 */ {4, 25, NULL}, - /* idx 21 */ {4, 25, NULL}, - /* idx 22 */ {4, 25, NULL}, - /* idx 23 */ {4, 25, NULL}, - /* idx 24 */ {4, 26, NULL}, - /* idx 25 */ {4, 26, NULL}, - /* idx 26 */ {4, 26, NULL}, - /* idx 27 */ {4, 26, NULL}, - /* idx 28 */ {4, 27, NULL}, - /* idx 29 */ {4, 27, NULL}, - /* idx 30 */ {4, 27, NULL}, - /* idx 31 */ {4, 27, NULL}, - /* idx 32 */ {4, 28, NULL}, - /* idx 33 */ {4, 28, NULL}, - /* idx 34 */ {4, 28, NULL}, - /* idx 35 */ {4, 28, NULL}, - /* idx 36 */ {4, 29, NULL}, - /* idx 37 */ {4, 29, NULL}, - /* idx 38 */ {4, 29, NULL}, - /* idx 39 */ {4, 29, NULL}, - /* idx 40 */ {4, 30, NULL}, - /* idx 41 */ {4, 30, NULL}, - /* idx 42 */ {4, 30, NULL}, - /* idx 43 */ {4, 30, NULL}, - /* idx 44 */ {4, 31, NULL}, - /* idx 45 */ {4, 31, NULL}, - /* idx 46 */ {4, 31, NULL}, - /* idx 47 */ {4, 31, NULL}, - /* idx 48 */ {4, 127, NULL}, - /* idx 49 */ {4, 127, NULL}, - /* idx 50 */ {4, 127, NULL}, - /* idx 51 */ {4, 127, NULL}, - /* idx 52 */ {4, 220, NULL}, - /* idx 53 */ {4, 220, NULL}, - /* idx 54 */ {4, 220, NULL}, - /* idx 55 */ {4, 220, NULL}, - /* idx 56 */ {4, 249, NULL}, - /* idx 57 */ {4, 249, NULL}, - /* idx 58 */ {4, 249, NULL}, - /* idx 59 */ {4, 249, NULL}, - /* idx 60 */ {6, 10, NULL}, - /* idx 61 */ {6, 13, NULL}, - /* idx 62 */ {6, 22, NULL}, - /* idx 63 */ {0, 0, NULL} -}; - -static struct stbl byte3_pref1111 = { - 6, - byte3_pref1111_array -}; - -static struct ssym byte2_pref0_array[] = { - /* idx 0 */ {3, 92, NULL}, /* '\' */ - /* idx 1 */ {3, 92, NULL}, /* '\' */ - /* idx 2 */ {3, 92, NULL}, /* '\' */ - /* idx 3 */ {3, 92, NULL}, /* '\' */ - /* idx 4 */ {3, 195, NULL}, /* . */ - /* idx 5 */ {3, 195, NULL}, /* . */ - /* idx 6 */ {3, 195, NULL}, /* . */ - /* idx 7 */ {3, 195, NULL}, /* . */ - /* idx 8 */ {3, 208, NULL}, /* . */ - /* idx 9 */ {3, 208, NULL}, /* . */ - /* idx 10 */ {3, 208, NULL}, /* . */ - /* idx 11 */ {3, 208, NULL}, /* . */ - /* idx 12 */ {4, 128, NULL}, /* . */ - /* idx 13 */ {4, 128, NULL}, /* . */ - /* idx 14 */ {4, 130, NULL}, /* . */ - /* idx 15 */ {4, 130, NULL}, /* . */ - /* idx 16 */ {4, 131, NULL}, /* . */ - /* idx 17 */ {4, 131, NULL}, /* . */ - /* idx 18 */ {4, 162, NULL}, /* . */ - /* idx 19 */ {4, 162, NULL}, /* . */ - /* idx 20 */ {4, 184, NULL}, /* . */ - /* idx 21 */ {4, 184, NULL}, /* . */ - /* idx 22 */ {4, 194, NULL}, /* . */ - /* idx 23 */ {4, 194, NULL}, /* . */ - /* idx 24 */ {4, 224, NULL}, /* . */ - /* idx 25 */ {4, 224, NULL}, /* . */ - /* idx 26 */ {4, 226, NULL}, /* . */ - /* idx 27 */ {4, 226, NULL}, /* . */ - /* idx 28 */ {5, 153, NULL}, /* . */ - /* idx 29 */ {5, 161, NULL}, /* . */ - /* idx 30 */ {5, 167, NULL}, /* . */ - /* idx 31 */ {5, 172, NULL} /* . */ -}; - -static struct stbl byte2_pref0 = { - 5, - byte2_pref0_array -}; - -static struct ssym byte2_pref1_array[] = { - /* idx 0 */ {5, 176, NULL}, /* . */ - /* idx 1 */ {5, 176, NULL}, /* . */ - /* idx 2 */ {5, 176, NULL}, /* . */ - /* idx 3 */ {5, 176, NULL}, /* . */ - /* idx 4 */ {5, 176, NULL}, /* . */ - /* idx 5 */ {5, 176, NULL}, /* . */ - /* idx 6 */ {5, 176, NULL}, /* . */ - /* idx 7 */ {5, 176, NULL}, /* . */ - /* idx 8 */ {5, 177, NULL}, /* . */ - /* idx 9 */ {5, 177, NULL}, /* . */ - /* idx 10 */ {5, 177, NULL}, /* . */ - /* idx 11 */ {5, 177, NULL}, /* . */ - /* idx 12 */ {5, 177, NULL}, /* . */ - /* idx 13 */ {5, 177, NULL}, /* . */ - /* idx 14 */ {5, 177, NULL}, /* . */ - /* idx 15 */ {5, 177, NULL}, /* . */ - /* idx 16 */ {5, 179, NULL}, /* */ - /* idx 17 */ {5, 179, NULL}, /* */ - /* idx 18 */ {5, 179, NULL}, /* */ - /* idx 19 */ {5, 179, NULL}, /* */ - /* idx 20 */ {5, 179, NULL}, /* */ - /* idx 21 */ {5, 179, NULL}, /* */ - /* idx 22 */ {5, 179, NULL}, /* */ - /* idx 23 */ {5, 179, NULL}, /* */ - /* idx 24 */ {5, 209, NULL}, /* . */ - /* idx 25 */ {5, 209, NULL}, /* . */ - /* idx 26 */ {5, 209, NULL}, /* . */ - /* idx 27 */ {5, 209, NULL}, /* . */ - /* idx 28 */ {5, 209, NULL}, /* . */ - /* idx 29 */ {5, 209, NULL}, /* . */ - /* idx 30 */ {5, 209, NULL}, /* . */ - /* idx 31 */ {5, 209, NULL}, /* . */ - /* idx 32 */ {5, 216, NULL}, /* . */ - /* idx 33 */ {5, 216, NULL}, /* . */ - /* idx 34 */ {5, 216, NULL}, /* . */ - /* idx 35 */ {5, 216, NULL}, /* . */ - /* idx 36 */ {5, 216, NULL}, /* . */ - /* idx 37 */ {5, 216, NULL}, /* . */ - /* idx 38 */ {5, 216, NULL}, /* . */ - /* idx 39 */ {5, 216, NULL}, /* . */ - /* idx 40 */ {5, 217, NULL}, /* . */ - /* idx 41 */ {5, 217, NULL}, /* . */ - /* idx 42 */ {5, 217, NULL}, /* . */ - /* idx 43 */ {5, 217, NULL}, /* . */ - /* idx 44 */ {5, 217, NULL}, /* . */ - /* idx 45 */ {5, 217, NULL}, /* . */ - /* idx 46 */ {5, 217, NULL}, /* . */ - /* idx 47 */ {5, 217, NULL}, /* . */ - /* idx 48 */ {5, 227, NULL}, /* . */ - /* idx 49 */ {5, 227, NULL}, /* . */ - /* idx 50 */ {5, 227, NULL}, /* . */ - /* idx 51 */ {5, 227, NULL}, /* . */ - /* idx 52 */ {5, 227, NULL}, /* . */ - /* idx 53 */ {5, 227, NULL}, /* . */ - /* idx 54 */ {5, 227, NULL}, /* . */ - /* idx 55 */ {5, 227, NULL}, /* . */ - /* idx 56 */ {5, 229, NULL}, /* . */ - /* idx 57 */ {5, 229, NULL}, /* . */ - /* idx 58 */ {5, 229, NULL}, /* . */ - /* idx 59 */ {5, 229, NULL}, /* . */ - /* idx 60 */ {5, 229, NULL}, /* . */ - /* idx 61 */ {5, 229, NULL}, /* . */ - /* idx 62 */ {5, 229, NULL}, /* . */ - /* idx 63 */ {5, 229, NULL}, /* . */ - /* idx 64 */ {5, 230, NULL}, /* . */ - /* idx 65 */ {5, 230, NULL}, /* . */ - /* idx 66 */ {5, 230, NULL}, /* . */ - /* idx 67 */ {5, 230, NULL}, /* . */ - /* idx 68 */ {5, 230, NULL}, /* . */ - /* idx 69 */ {5, 230, NULL}, /* . */ - /* idx 70 */ {5, 230, NULL}, /* . */ - /* idx 71 */ {5, 230, NULL}, /* . */ - /* idx 72 */ {6, 129, NULL}, /* . */ - /* idx 73 */ {6, 129, NULL}, /* . */ - /* idx 74 */ {6, 129, NULL}, /* . */ - /* idx 75 */ {6, 129, NULL}, /* . */ - /* idx 76 */ {6, 132, NULL}, /* . */ - /* idx 77 */ {6, 132, NULL}, /* . */ - /* idx 78 */ {6, 132, NULL}, /* . */ - /* idx 79 */ {6, 132, NULL}, /* . */ - /* idx 80 */ {6, 133, NULL}, /* . */ - /* idx 81 */ {6, 133, NULL}, /* . */ - /* idx 82 */ {6, 133, NULL}, /* . */ - /* idx 83 */ {6, 133, NULL}, /* . */ - /* idx 84 */ {6, 134, NULL}, /* . */ - /* idx 85 */ {6, 134, NULL}, /* . */ - /* idx 86 */ {6, 134, NULL}, /* . */ - /* idx 87 */ {6, 134, NULL}, /* . */ - /* idx 88 */ {6, 136, NULL}, /* . */ - /* idx 89 */ {6, 136, NULL}, /* . */ - /* idx 90 */ {6, 136, NULL}, /* . */ - /* idx 91 */ {6, 136, NULL}, /* . */ - /* idx 92 */ {6, 146, NULL}, /* . */ - /* idx 93 */ {6, 146, NULL}, /* . */ - /* idx 94 */ {6, 146, NULL}, /* . */ - /* idx 95 */ {6, 146, NULL}, /* . */ - /* idx 96 */ {6, 154, NULL}, /* . */ - /* idx 97 */ {6, 154, NULL}, /* . */ - /* idx 98 */ {6, 154, NULL}, /* . */ - /* idx 99 */ {6, 154, NULL}, /* . */ - /* idx 100 */ {6, 156, NULL}, /* . */ - /* idx 101 */ {6, 156, NULL}, /* . */ - /* idx 102 */ {6, 156, NULL}, /* . */ - /* idx 103 */ {6, 156, NULL}, /* . */ - /* idx 104 */ {6, 160, NULL}, /* . */ - /* idx 105 */ {6, 160, NULL}, /* . */ - /* idx 106 */ {6, 160, NULL}, /* . */ - /* idx 107 */ {6, 160, NULL}, /* . */ - /* idx 108 */ {6, 163, NULL}, /* . */ - /* idx 109 */ {6, 163, NULL}, /* . */ - /* idx 110 */ {6, 163, NULL}, /* . */ - /* idx 111 */ {6, 163, NULL}, /* . */ - /* idx 112 */ {6, 164, NULL}, /* . */ - /* idx 113 */ {6, 164, NULL}, /* . */ - /* idx 114 */ {6, 164, NULL}, /* . */ - /* idx 115 */ {6, 164, NULL}, /* . */ - /* idx 116 */ {6, 169, NULL}, /* . */ - /* idx 117 */ {6, 169, NULL}, /* . */ - /* idx 118 */ {6, 169, NULL}, /* . */ - /* idx 119 */ {6, 169, NULL}, /* . */ - /* idx 120 */ {6, 170, NULL}, /* . */ - /* idx 121 */ {6, 170, NULL}, /* . */ - /* idx 122 */ {6, 170, NULL}, /* . */ - /* idx 123 */ {6, 170, NULL}, /* . */ - /* idx 124 */ {6, 173, NULL}, /* . */ - /* idx 125 */ {6, 173, NULL}, /* . */ - /* idx 126 */ {6, 173, NULL}, /* . */ - /* idx 127 */ {6, 173, NULL}, /* . */ - /* idx 128 */ {6, 176, NULL}, /* . */ - /* idx 129 */ {6, 176, NULL}, /* . */ - /* idx 130 */ {6, 176, NULL}, /* . */ - /* idx 131 */ {6, 176, NULL}, /* . */ - /* idx 132 */ {6, 181, NULL}, /* . */ - /* idx 133 */ {6, 181, NULL}, /* . */ - /* idx 134 */ {6, 181, NULL}, /* . */ - /* idx 135 */ {6, 181, NULL}, /* . */ - /* idx 136 */ {6, 185, NULL}, /* . */ - /* idx 137 */ {6, 185, NULL}, /* . */ - /* idx 138 */ {6, 185, NULL}, /* . */ - /* idx 139 */ {6, 185, NULL}, /* . */ - /* idx 140 */ {6, 186, NULL}, /* . */ - /* idx 141 */ {6, 186, NULL}, /* . */ - /* idx 142 */ {6, 186, NULL}, /* . */ - /* idx 143 */ {6, 186, NULL}, /* . */ - /* idx 144 */ {6, 187, NULL}, /* . */ - /* idx 145 */ {6, 187, NULL}, /* . */ - /* idx 146 */ {6, 187, NULL}, /* . */ - /* idx 147 */ {6, 187, NULL}, /* . */ - /* idx 148 */ {6, 189, NULL}, /* . */ - /* idx 149 */ {6, 189, NULL}, /* . */ - /* idx 150 */ {6, 189, NULL}, /* . */ - /* idx 151 */ {6, 189, NULL}, /* . */ - /* idx 152 */ {6, 190, NULL}, /* . */ - /* idx 153 */ {6, 190, NULL}, /* . */ - /* idx 154 */ {6, 190, NULL}, /* . */ - /* idx 155 */ {6, 190, NULL}, /* . */ - /* idx 156 */ {6, 196, NULL}, /* . */ - /* idx 157 */ {6, 196, NULL}, /* . */ - /* idx 158 */ {6, 196, NULL}, /* . */ - /* idx 159 */ {6, 196, NULL}, /* . */ - /* idx 160 */ {6, 198, NULL}, /* . */ - /* idx 161 */ {6, 198, NULL}, /* . */ - /* idx 162 */ {6, 198, NULL}, /* . */ - /* idx 163 */ {6, 198, NULL}, /* . */ - /* idx 164 */ {6, 228, NULL}, /* . */ - /* idx 165 */ {6, 228, NULL}, /* . */ - /* idx 166 */ {6, 228, NULL}, /* . */ - /* idx 167 */ {6, 228, NULL}, /* . */ - /* idx 168 */ {6, 232, NULL}, /* . */ - /* idx 169 */ {6, 232, NULL}, /* . */ - /* idx 170 */ {6, 232, NULL}, /* . */ - /* idx 171 */ {6, 232, NULL}, /* . */ - /* idx 172 */ {6, 233, NULL}, /* . */ - /* idx 173 */ {6, 233, NULL}, /* . */ - /* idx 174 */ {6, 233, NULL}, /* . */ - /* idx 175 */ {6, 233, NULL}, /* . */ - /* idx 176 */ {7, 1, NULL}, - /* idx 177 */ {7, 1, NULL}, - /* idx 178 */ {7, 135, NULL}, - /* idx 179 */ {7, 135, NULL}, - /* idx 180 */ {7, 137, NULL}, - /* idx 181 */ {7, 137, NULL}, - /* idx 182 */ {7, 138, NULL}, - /* idx 183 */ {7, 138, NULL}, - /* idx 184 */ {7, 139, NULL}, - /* idx 185 */ {7, 139, NULL}, - /* idx 186 */ {7, 140, NULL}, - /* idx 187 */ {7, 140, NULL}, - /* idx 188 */ {7, 141, NULL}, - /* idx 189 */ {7, 141, NULL}, - /* idx 190 */ {7, 143, NULL}, - /* idx 191 */ {7, 143, NULL}, - /* idx 192 */ {7, 147, NULL}, - /* idx 193 */ {7, 147, NULL}, - /* idx 194 */ {7, 149, NULL}, - /* idx 195 */ {7, 149, NULL}, - /* idx 196 */ {7, 150, NULL}, - /* idx 197 */ {7, 150, NULL}, - /* idx 198 */ {7, 151, NULL}, - /* idx 199 */ {7, 151, NULL}, - /* idx 200 */ {7, 152, NULL}, - /* idx 201 */ {7, 152, NULL}, - /* idx 202 */ {7, 155, NULL}, - /* idx 203 */ {7, 155, NULL}, - /* idx 204 */ {7, 157, NULL}, - /* idx 205 */ {7, 157, NULL}, - /* idx 206 */ {7, 158, NULL}, - /* idx 207 */ {7, 158, NULL}, - /* idx 208 */ {7, 165, NULL}, - /* idx 209 */ {7, 165, NULL}, - /* idx 210 */ {7, 166, NULL}, - /* idx 211 */ {7, 166, NULL}, - /* idx 212 */ {7, 168, NULL}, - /* idx 213 */ {7, 168, NULL}, - /* idx 214 */ {7, 174, NULL}, - /* idx 215 */ {7, 174, NULL}, - /* idx 216 */ {7, 175, NULL}, - /* idx 217 */ {7, 175, NULL}, - /* idx 218 */ {7, 180, NULL}, - /* idx 219 */ {7, 180, NULL}, - /* idx 220 */ {7, 182, NULL}, - /* idx 221 */ {7, 182, NULL}, - /* idx 222 */ {7, 183, NULL}, - /* idx 223 */ {7, 183, NULL}, - /* idx 224 */ {7, 188, NULL}, - /* idx 225 */ {7, 188, NULL}, - /* idx 226 */ {7, 191, NULL}, - /* idx 227 */ {7, 191, NULL}, - /* idx 228 */ {7, 197, NULL}, - /* idx 229 */ {7, 197, NULL}, - /* idx 230 */ {7, 231, NULL}, - /* idx 231 */ {7, 231, NULL}, - /* idx 232 */ {7, 239, NULL}, - /* idx 233 */ {7, 239, NULL}, - /* idx 234 */ {8, 9, NULL}, /* tab */ - /* idx 235 */ {8, 142, NULL}, - /* idx 236 */ {8, 144, NULL}, - /* idx 237 */ {8, 145, NULL}, - /* idx 238 */ {8, 148, NULL}, - /* idx 239 */ {8, 159, NULL}, - /* idx 240 */ {8, 171, NULL}, - /* idx 241 */ {8, 206, NULL}, - /* idx 242 */ {8, 215, NULL}, - /* idx 243 */ {8, 225, NULL}, - /* idx 244 */ {8, 236, NULL}, - /* idx 245 */ {8, 237, NULL}, - /* idx 246 */ {8, 0, &byte3_pref0110 }, - /* idx 247 */ {8, 0, &byte3_pref0111 }, - /* idx 248 */ {8, 0, &byte3_pref1000 }, - /* idx 249 */ {8, 0, &byte3_pref1001 }, - /* idx 250 */ {8, 0, &byte3_pref1010 }, - /* idx 251 */ {8, 0, &byte3_pref1011 }, - /* idx 252 */ {8, 0, &byte3_pref1100 }, - /* idx 253 */ {8, 0, &byte3_pref1101 }, - /* idx 254 */ {8, 0, &byte3_pref1110 }, - /* idx 255 */ {8, 0, &byte3_pref1111 } -}; - -static struct stbl byte2_pref1 = { - 8, - byte2_pref1_array -}; - -static struct ssym byte1_pref0_array[] = { - /* idx 0 */ {2, 33, NULL}, /* '!' */ - /* idx 1 */ {2, 34, NULL}, /* '"' */ - /* idx 2 */ {2, 40, NULL}, /* '(' */ - /* idx 3 */ {2, 41, NULL}, /* ')' */ -}; - -static struct stbl byte1_pref0 = { - 2, - byte1_pref0_array -}; - -static struct ssym byte1_pref1_array[] = { - /* idx 0 */ {2, 63, NULL}, /* '?' */ - /* idx 1 */ {2, 63, NULL}, /* '?' */ - /* idx 2 */ {2, 63, NULL}, /* '?' */ - /* idx 3 */ {2, 63, NULL}, /* '?' */ - /* idx 4 */ {2, 63, NULL}, /* '?' */ - /* idx 5 */ {2, 63, NULL}, /* '?' */ - /* idx 6 */ {2, 63, NULL}, /* '?' */ - /* idx 7 */ {2, 63, NULL}, /* '?' */ - /* idx 8 */ {2, 63, NULL}, /* '?' */ - /* idx 9 */ {2, 63, NULL}, /* '?' */ - /* idx 10 */ {2, 63, NULL}, /* '?' */ - /* idx 11 */ {2, 63, NULL}, /* '?' */ - /* idx 12 */ {2, 63, NULL}, /* '?' */ - /* idx 13 */ {2, 63, NULL}, /* '?' */ - /* idx 14 */ {2, 63, NULL}, /* '?' */ - /* idx 15 */ {2, 63, NULL}, /* '?' */ - /* idx 16 */ {2, 63, NULL}, /* '?' */ - /* idx 17 */ {2, 63, NULL}, /* '?' */ - /* idx 18 */ {2, 63, NULL}, /* '?' */ - /* idx 19 */ {2, 63, NULL}, /* '?' */ - /* idx 20 */ {2, 63, NULL}, /* '?' */ - /* idx 21 */ {2, 63, NULL}, /* '?' */ - /* idx 22 */ {2, 63, NULL}, /* '?' */ - /* idx 23 */ {2, 63, NULL}, /* '?' */ - /* idx 24 */ {2, 63, NULL}, /* '?' */ - /* idx 25 */ {2, 63, NULL}, /* '?' */ - /* idx 26 */ {2, 63, NULL}, /* '?' */ - /* idx 27 */ {2, 63, NULL}, /* '?' */ - /* idx 28 */ {2, 63, NULL}, /* '?' */ - /* idx 29 */ {2, 63, NULL}, /* '?' */ - /* idx 30 */ {2, 63, NULL}, /* '?' */ - /* idx 31 */ {2, 63, NULL}, /* '?' */ - /* idx 32 */ {2, 63, NULL}, /* '?' */ - /* idx 33 */ {2, 63, NULL}, /* '?' */ - /* idx 34 */ {2, 63, NULL}, /* '?' */ - /* idx 35 */ {2, 63, NULL}, /* '?' */ - /* idx 36 */ {2, 63, NULL}, /* '?' */ - /* idx 37 */ {2, 63, NULL}, /* '?' */ - /* idx 38 */ {2, 63, NULL}, /* '?' */ - /* idx 39 */ {2, 63, NULL}, /* '?' */ - /* idx 40 */ {2, 63, NULL}, /* '?' */ - /* idx 41 */ {2, 63, NULL}, /* '?' */ - /* idx 42 */ {2, 63, NULL}, /* '?' */ - /* idx 43 */ {2, 63, NULL}, /* '?' */ - /* idx 44 */ {2, 63, NULL}, /* '?' */ - /* idx 45 */ {2, 63, NULL}, /* '?' */ - /* idx 46 */ {2, 63, NULL}, /* '?' */ - /* idx 47 */ {2, 63, NULL}, /* '?' */ - /* idx 48 */ {2, 63, NULL}, /* '?' */ - /* idx 49 */ {2, 63, NULL}, /* '?' */ - /* idx 50 */ {2, 63, NULL}, /* '?' */ - /* idx 51 */ {2, 63, NULL}, /* '?' */ - /* idx 52 */ {2, 63, NULL}, /* '?' */ - /* idx 53 */ {2, 63, NULL}, /* '?' */ - /* idx 54 */ {2, 63, NULL}, /* '?' */ - /* idx 55 */ {2, 63, NULL}, /* '?' */ - /* idx 56 */ {2, 63, NULL}, /* '?' */ - /* idx 57 */ {2, 63, NULL}, /* '?' */ - /* idx 58 */ {2, 63, NULL}, /* '?' */ - /* idx 59 */ {2, 63, NULL}, /* '?' */ - /* idx 60 */ {2, 63, NULL}, /* '?' */ - /* idx 61 */ {2, 63, NULL}, /* '?' */ - /* idx 62 */ {2, 63, NULL}, /* '?' */ - /* idx 63 */ {2, 63, NULL}, /* '?' */ - /* idx 64 */ {3, 39, NULL}, /* ''' */ - /* idx 65 */ {3, 39, NULL}, /* ''' */ - /* idx 66 */ {3, 39, NULL}, /* ''' */ - /* idx 67 */ {3, 39, NULL}, /* ''' */ - /* idx 68 */ {3, 39, NULL}, /* ''' */ - /* idx 69 */ {3, 39, NULL}, /* ''' */ - /* idx 70 */ {3, 39, NULL}, /* ''' */ - /* idx 71 */ {3, 39, NULL}, /* ''' */ - /* idx 72 */ {3, 39, NULL}, /* ''' */ - /* idx 73 */ {3, 39, NULL}, /* ''' */ - /* idx 74 */ {3, 39, NULL}, /* ''' */ - /* idx 75 */ {3, 39, NULL}, /* ''' */ - /* idx 76 */ {3, 39, NULL}, /* ''' */ - /* idx 77 */ {3, 39, NULL}, /* ''' */ - /* idx 78 */ {3, 39, NULL}, /* ''' */ - /* idx 79 */ {3, 39, NULL}, /* ''' */ - /* idx 80 */ {3, 39, NULL}, /* ''' */ - /* idx 81 */ {3, 39, NULL}, /* ''' */ - /* idx 82 */ {3, 39, NULL}, /* ''' */ - /* idx 83 */ {3, 39, NULL}, /* ''' */ - /* idx 84 */ {3, 39, NULL}, /* ''' */ - /* idx 85 */ {3, 39, NULL}, /* ''' */ - /* idx 86 */ {3, 39, NULL}, /* ''' */ - /* idx 87 */ {3, 39, NULL}, /* ''' */ - /* idx 88 */ {3, 39, NULL}, /* ''' */ - /* idx 89 */ {3, 39, NULL}, /* ''' */ - /* idx 90 */ {3, 39, NULL}, /* ''' */ - /* idx 91 */ {3, 39, NULL}, /* ''' */ - /* idx 92 */ {3, 39, NULL}, /* ''' */ - /* idx 93 */ {3, 39, NULL}, /* ''' */ - /* idx 94 */ {3, 39, NULL}, /* ''' */ - /* idx 95 */ {3, 39, NULL}, /* ''' */ - /* idx 96 */ {3, 43, NULL}, /* '+' */ - /* idx 97 */ {3, 43, NULL}, /* '+' */ - /* idx 98 */ {3, 43, NULL}, /* '+' */ - /* idx 99 */ {3, 43, NULL}, /* '+' */ - /* idx 100 */ {3, 43, NULL}, /* '+' */ - /* idx 101 */ {3, 43, NULL}, /* '+' */ - /* idx 102 */ {3, 43, NULL}, /* '+' */ - /* idx 103 */ {3, 43, NULL}, /* '+' */ - /* idx 104 */ {3, 43, NULL}, /* '+' */ - /* idx 105 */ {3, 43, NULL}, /* '+' */ - /* idx 106 */ {3, 43, NULL}, /* '+' */ - /* idx 107 */ {3, 43, NULL}, /* '+' */ - /* idx 108 */ {3, 43, NULL}, /* '+' */ - /* idx 109 */ {3, 43, NULL}, /* '+' */ - /* idx 110 */ {3, 43, NULL}, /* '+' */ - /* idx 111 */ {3, 43, NULL}, /* '+' */ - /* idx 112 */ {3, 43, NULL}, /* '+' */ - /* idx 113 */ {3, 43, NULL}, /* '+' */ - /* idx 114 */ {3, 43, NULL}, /* '+' */ - /* idx 115 */ {3, 43, NULL}, /* '+' */ - /* idx 116 */ {3, 43, NULL}, /* '+' */ - /* idx 117 */ {3, 43, NULL}, /* '+' */ - /* idx 118 */ {3, 43, NULL}, /* '+' */ - /* idx 119 */ {3, 43, NULL}, /* '+' */ - /* idx 120 */ {3, 43, NULL}, /* '+' */ - /* idx 121 */ {3, 43, NULL}, /* '+' */ - /* idx 122 */ {3, 43, NULL}, /* '+' */ - /* idx 123 */ {3, 43, NULL}, /* '+' */ - /* idx 124 */ {3, 43, NULL}, /* '+' */ - /* idx 125 */ {3, 43, NULL}, /* '+' */ - /* idx 126 */ {3, 43, NULL}, /* '+' */ - /* idx 127 */ {3, 43, NULL}, /* '+' */ - /* idx 128 */ {3, 124, NULL}, /* '|' */ - /* idx 129 */ {3, 124, NULL}, /* '|' */ - /* idx 130 */ {3, 124, NULL}, /* '|' */ - /* idx 131 */ {3, 124, NULL}, /* '|' */ - /* idx 132 */ {3, 124, NULL}, /* '|' */ - /* idx 133 */ {3, 124, NULL}, /* '|' */ - /* idx 134 */ {3, 124, NULL}, /* '|' */ - /* idx 135 */ {3, 124, NULL}, /* '|' */ - /* idx 136 */ {3, 124, NULL}, /* '|' */ - /* idx 137 */ {3, 124, NULL}, /* '|' */ - /* idx 138 */ {3, 124, NULL}, /* '|' */ - /* idx 139 */ {3, 124, NULL}, /* '|' */ - /* idx 140 */ {3, 124, NULL}, /* '|' */ - /* idx 141 */ {3, 124, NULL}, /* '|' */ - /* idx 142 */ {3, 124, NULL}, /* '|' */ - /* idx 143 */ {3, 124, NULL}, /* '|' */ - /* idx 144 */ {3, 124, NULL}, /* '|' */ - /* idx 145 */ {3, 124, NULL}, /* '|' */ - /* idx 146 */ {3, 124, NULL}, /* '|' */ - /* idx 147 */ {3, 124, NULL}, /* '|' */ - /* idx 148 */ {3, 124, NULL}, /* '|' */ - /* idx 149 */ {3, 124, NULL}, /* '|' */ - /* idx 150 */ {3, 124, NULL}, /* '|' */ - /* idx 151 */ {3, 124, NULL}, /* '|' */ - /* idx 152 */ {3, 124, NULL}, /* '|' */ - /* idx 153 */ {3, 124, NULL}, /* '|' */ - /* idx 154 */ {3, 124, NULL}, /* '|' */ - /* idx 155 */ {3, 124, NULL}, /* '|' */ - /* idx 156 */ {3, 124, NULL}, /* '|' */ - /* idx 157 */ {3, 124, NULL}, /* '|' */ - /* idx 158 */ {3, 124, NULL}, /* '|' */ - /* idx 159 */ {3, 124, NULL}, /* '|' */ - /* idx 160 */ {4, 35, NULL}, /* '#' */ - /* idx 161 */ {4, 35, NULL}, /* '#' */ - /* idx 162 */ {4, 35, NULL}, /* '#' */ - /* idx 163 */ {4, 35, NULL}, /* '#' */ - /* idx 164 */ {4, 35, NULL}, /* '#' */ - /* idx 165 */ {4, 35, NULL}, /* '#' */ - /* idx 166 */ {4, 35, NULL}, /* '#' */ - /* idx 167 */ {4, 35, NULL}, /* '#' */ - /* idx 168 */ {4, 35, NULL}, /* '#' */ - /* idx 169 */ {4, 35, NULL}, /* '#' */ - /* idx 170 */ {4, 35, NULL}, /* '#' */ - /* idx 171 */ {4, 35, NULL}, /* '#' */ - /* idx 172 */ {4, 35, NULL}, /* '#' */ - /* idx 173 */ {4, 35, NULL}, /* '#' */ - /* idx 174 */ {4, 35, NULL}, /* '#' */ - /* idx 175 */ {4, 35, NULL}, /* '#' */ - /* idx 176 */ {4, 62, NULL}, /* '>' */ - /* idx 177 */ {4, 62, NULL}, /* '>' */ - /* idx 178 */ {4, 62, NULL}, /* '>' */ - /* idx 179 */ {4, 62, NULL}, /* '>' */ - /* idx 180 */ {4, 62, NULL}, /* '>' */ - /* idx 181 */ {4, 62, NULL}, /* '>' */ - /* idx 182 */ {4, 62, NULL}, /* '>' */ - /* idx 183 */ {4, 62, NULL}, /* '>' */ - /* idx 184 */ {4, 62, NULL}, /* '>' */ - /* idx 185 */ {4, 62, NULL}, /* '>' */ - /* idx 186 */ {4, 62, NULL}, /* '>' */ - /* idx 187 */ {4, 62, NULL}, /* '>' */ - /* idx 188 */ {4, 62, NULL}, /* '>' */ - /* idx 189 */ {4, 62, NULL}, /* '>' */ - /* idx 190 */ {4, 62, NULL}, /* '>' */ - /* idx 191 */ {4, 62, NULL}, /* '>' */ - /* idx 192 */ {5, 0, NULL}, /* . */ - /* idx 193 */ {5, 0, NULL}, /* . */ - /* idx 194 */ {5, 0, NULL}, /* . */ - /* idx 195 */ {5, 0, NULL}, /* . */ - /* idx 196 */ {5, 0, NULL}, /* . */ - /* idx 197 */ {5, 0, NULL}, /* . */ - /* idx 198 */ {5, 0, NULL}, /* . */ - /* idx 199 */ {5, 0, NULL}, /* . */ - /* idx 200 */ {5, 36, NULL}, /* $ */ - /* idx 201 */ {5, 36, NULL}, /* $ */ - /* idx 202 */ {5, 36, NULL}, /* $ */ - /* idx 203 */ {5, 36, NULL}, /* $ */ - /* idx 204 */ {5, 36, NULL}, /* $ */ - /* idx 205 */ {5, 36, NULL}, /* $ */ - /* idx 206 */ {5, 36, NULL}, /* $ */ - /* idx 207 */ {5, 36, NULL}, /* $ */ - /* idx 208 */ {5, 64, NULL}, /* '@' */ - /* idx 209 */ {5, 64, NULL}, /* '@' */ - /* idx 210 */ {5, 64, NULL}, /* '@' */ - /* idx 211 */ {5, 64, NULL}, /* '@' */ - /* idx 212 */ {5, 64, NULL}, /* '@' */ - /* idx 213 */ {5, 64, NULL}, /* '@' */ - /* idx 214 */ {5, 64, NULL}, /* '@' */ - /* idx 215 */ {5, 64, NULL}, /* '@' */ - /* idx 216 */ {5, 91, NULL}, /* '[' */ - /* idx 217 */ {5, 91, NULL}, /* '[' */ - /* idx 218 */ {5, 91, NULL}, /* '[' */ - /* idx 219 */ {5, 91, NULL}, /* '[' */ - /* idx 220 */ {5, 91, NULL}, /* '[' */ - /* idx 221 */ {5, 91, NULL}, /* '[' */ - /* idx 222 */ {5, 91, NULL}, /* '[' */ - /* idx 223 */ {5, 91, NULL}, /* '[' */ - /* idx 224 */ {5, 93, NULL}, /* ']' */ - /* idx 225 */ {5, 93, NULL}, /* ']' */ - /* idx 226 */ {5, 93, NULL}, /* ']' */ - /* idx 227 */ {5, 93, NULL}, /* ']' */ - /* idx 228 */ {5, 93, NULL}, /* ']' */ - /* idx 229 */ {5, 93, NULL}, /* ']' */ - /* idx 230 */ {5, 93, NULL}, /* ']' */ - /* idx 231 */ {5, 93, NULL}, /* ']' */ - /* idx 232 */ {5, 126, NULL}, /* '~' */ - /* idx 233 */ {5, 126, NULL}, /* '~' */ - /* idx 234 */ {5, 126, NULL}, /* '~' */ - /* idx 235 */ {5, 126, NULL}, /* '~' */ - /* idx 236 */ {5, 126, NULL}, /* '~' */ - /* idx 237 */ {5, 126, NULL}, /* '~' */ - /* idx 238 */ {5, 126, NULL}, /* '~' */ - /* idx 239 */ {5, 126, NULL}, /* '~' */ - /* idx 240 */ {6, 94, NULL}, /* '^' */ - /* idx 241 */ {6, 94, NULL}, /* '^' */ - /* idx 242 */ {6, 94, NULL}, /* '^' */ - /* idx 243 */ {6, 94, NULL}, /* '^' */ - /* idx 244 */ {6, 125, NULL}, /* '}' */ - /* idx 245 */ {6, 125, NULL}, /* '}' */ - /* idx 246 */ {6, 125, NULL}, /* '}' */ - /* idx 247 */ {6, 125, NULL}, /* '}' */ - /* idx 248 */ {7, 60, NULL}, /* '<' */ - /* idx 249 */ {7, 60, NULL}, /* '<' */ - /* idx 250 */ {7, 96, NULL}, /* '`' */ - /* idx 251 */ {7, 96, NULL}, /* '`' */ - /* idx 252 */ {7, 123, NULL}, /* '{' */ - /* idx 253 */ {7, 123, NULL}, /* '{' */ - /* idx 254 */ {8, 0, &byte2_pref0}, /* escape */ - /* idx 255 */ {8, 0, &byte2_pref1} /* escape */ -}; - -static struct stbl byte1_pref1 = { - 8, - byte1_pref1_array -}; - -static struct ssym byte0_array[] = { - /* idx 0 */ {5, 48, NULL}, /* '0' */ - /* idx 1 */ {5, 48, NULL}, /* '0' */ - /* idx 2 */ {5, 48, NULL}, /* '0' */ - /* idx 3 */ {5, 48, NULL}, /* '0' */ - /* idx 4 */ {5, 48, NULL}, /* '0' */ - /* idx 5 */ {5, 48, NULL}, /* '0' */ - /* idx 6 */ {5, 48, NULL}, /* '0' */ - /* idx 7 */ {5, 48, NULL}, /* '0' */ - /* idx 8 */ {5, 49, NULL}, /* '1' */ - /* idx 9 */ {5, 49, NULL}, /* '1' */ - /* idx 10 */ {5, 49, NULL}, /* '1' */ - /* idx 11 */ {5, 49, NULL}, /* '1' */ - /* idx 12 */ {5, 49, NULL}, /* '1' */ - /* idx 13 */ {5, 49, NULL}, /* '1' */ - /* idx 14 */ {5, 49, NULL}, /* '1' */ - /* idx 15 */ {5, 49, NULL}, /* '1' */ - /* idx 16 */ {5, 50, NULL}, /* '2' */ - /* idx 17 */ {5, 50, NULL}, /* '2' */ - /* idx 18 */ {5, 50, NULL}, /* '2' */ - /* idx 19 */ {5, 50, NULL}, /* '2' */ - /* idx 20 */ {5, 50, NULL}, /* '2' */ - /* idx 21 */ {5, 50, NULL}, /* '2' */ - /* idx 22 */ {5, 50, NULL}, /* '2' */ - /* idx 23 */ {5, 50, NULL}, /* '2' */ - /* idx 24 */ {5, 97, NULL}, /* 'a' */ - /* idx 25 */ {5, 97, NULL}, /* 'a' */ - /* idx 26 */ {5, 97, NULL}, /* 'a' */ - /* idx 27 */ {5, 97, NULL}, /* 'a' */ - /* idx 28 */ {5, 97, NULL}, /* 'a' */ - /* idx 29 */ {5, 97, NULL}, /* 'a' */ - /* idx 30 */ {5, 97, NULL}, /* 'a' */ - /* idx 31 */ {5, 97, NULL}, /* 'a' */ - /* idx 32 */ {5, 99, NULL}, /* 'c' */ - /* idx 33 */ {5, 99, NULL}, /* 'c' */ - /* idx 34 */ {5, 99, NULL}, /* 'c' */ - /* idx 35 */ {5, 99, NULL}, /* 'c' */ - /* idx 36 */ {5, 99, NULL}, /* 'c' */ - /* idx 37 */ {5, 99, NULL}, /* 'c' */ - /* idx 38 */ {5, 99, NULL}, /* 'c' */ - /* idx 39 */ {5, 99, NULL}, /* 'c' */ - /* idx 40 */ {5, 101, NULL}, /* 'e' */ - /* idx 41 */ {5, 101, NULL}, /* 'e' */ - /* idx 42 */ {5, 101, NULL}, /* 'e' */ - /* idx 43 */ {5, 101, NULL}, /* 'e' */ - /* idx 44 */ {5, 101, NULL}, /* 'e' */ - /* idx 45 */ {5, 101, NULL}, /* 'e' */ - /* idx 46 */ {5, 101, NULL}, /* 'e' */ - /* idx 47 */ {5, 101, NULL}, /* 'e' */ - /* idx 48 */ {5, 105, NULL}, /* 'i' */ - /* idx 49 */ {5, 105, NULL}, /* 'i' */ - /* idx 50 */ {5, 105, NULL}, /* 'i' */ - /* idx 51 */ {5, 105, NULL}, /* 'i' */ - /* idx 52 */ {5, 105, NULL}, /* 'i' */ - /* idx 53 */ {5, 105, NULL}, /* 'i' */ - /* idx 54 */ {5, 105, NULL}, /* 'i' */ - /* idx 55 */ {5, 105, NULL}, /* 'i' */ - /* idx 56 */ {5, 111, NULL}, /* 'o' */ - /* idx 57 */ {5, 111, NULL}, /* 'o' */ - /* idx 58 */ {5, 111, NULL}, /* 'o' */ - /* idx 59 */ {5, 111, NULL}, /* 'o' */ - /* idx 60 */ {5, 111, NULL}, /* 'o' */ - /* idx 61 */ {5, 111, NULL}, /* 'o' */ - /* idx 62 */ {5, 111, NULL}, /* 'o' */ - /* idx 63 */ {5, 111, NULL}, /* 'o' */ - /* idx 64 */ {5, 115, NULL}, /* 's' */ - /* idx 65 */ {5, 115, NULL}, /* 's' */ - /* idx 66 */ {5, 115, NULL}, /* 's' */ - /* idx 67 */ {5, 115, NULL}, /* 's' */ - /* idx 68 */ {5, 115, NULL}, /* 's' */ - /* idx 69 */ {5, 115, NULL}, /* 's' */ - /* idx 70 */ {5, 115, NULL}, /* 's' */ - /* idx 71 */ {5, 115, NULL}, /* 's' */ - /* idx 72 */ {5, 116, NULL}, /* 't' */ - /* idx 73 */ {5, 116, NULL}, /* 't' */ - /* idx 74 */ {5, 116, NULL}, /* 't' */ - /* idx 75 */ {5, 116, NULL}, /* 't' */ - /* idx 76 */ {5, 116, NULL}, /* 't' */ - /* idx 77 */ {5, 116, NULL}, /* 't' */ - /* idx 78 */ {5, 116, NULL}, /* 't' */ - /* idx 79 */ {5, 116, NULL}, /* 't' */ - /* idx 80 */ {6, 32, NULL}, /* ' ' */ - /* idx 81 */ {6, 32, NULL}, /* ' ' */ - /* idx 82 */ {6, 32, NULL}, /* ' ' */ - /* idx 83 */ {6, 32, NULL}, /* ' ' */ - /* idx 84 */ {6, 37, NULL}, /* '%' */ - /* idx 85 */ {6, 37, NULL}, /* '%' */ - /* idx 86 */ {6, 37, NULL}, /* '%' */ - /* idx 87 */ {6, 37, NULL}, /* '%' */ - /* idx 88 */ {6, 45, NULL}, /* '-' */ - /* idx 89 */ {6, 45, NULL}, /* '-' */ - /* idx 90 */ {6, 45, NULL}, /* '-' */ - /* idx 91 */ {6, 45, NULL}, /* '-' */ - /* idx 92 */ {6, 46, NULL}, /* '.' */ - /* idx 93 */ {6, 46, NULL}, /* '.' */ - /* idx 94 */ {6, 46, NULL}, /* '.' */ - /* idx 95 */ {6, 46, NULL}, /* '.' */ - /* idx 96 */ {6, 47, NULL}, /* '/' */ - /* idx 97 */ {6, 47, NULL}, /* '/' */ - /* idx 98 */ {6, 47, NULL}, /* '/' */ - /* idx 99 */ {6, 47, NULL}, /* '/' */ - /* idx 100 */ {6, 51, NULL}, /* '3' */ - /* idx 101 */ {6, 51, NULL}, /* '3' */ - /* idx 102 */ {6, 51, NULL}, /* '3' */ - /* idx 103 */ {6, 51, NULL}, /* '3' */ - /* idx 104 */ {6, 52, NULL}, /* '4' */ - /* idx 105 */ {6, 52, NULL}, /* '4' */ - /* idx 106 */ {6, 52, NULL}, /* '4' */ - /* idx 107 */ {6, 52, NULL}, /* '4' */ - /* idx 108 */ {6, 53, NULL}, /* '5' */ - /* idx 109 */ {6, 53, NULL}, /* '5' */ - /* idx 110 */ {6, 53, NULL}, /* '5' */ - /* idx 111 */ {6, 53, NULL}, /* '5' */ - /* idx 112 */ {6, 54, NULL}, /* '6' */ - /* idx 113 */ {6, 54, NULL}, /* '6' */ - /* idx 114 */ {6, 54, NULL}, /* '6' */ - /* idx 115 */ {6, 54, NULL}, /* '6' */ - /* idx 116 */ {6, 55, NULL}, /* '7' */ - /* idx 117 */ {6, 55, NULL}, /* '7' */ - /* idx 118 */ {6, 55, NULL}, /* '7' */ - /* idx 119 */ {6, 55, NULL}, /* '7' */ - /* idx 120 */ {6, 56, NULL}, /* '8' */ - /* idx 121 */ {6, 56, NULL}, /* '8' */ - /* idx 122 */ {6, 56, NULL}, /* '8' */ - /* idx 123 */ {6, 56, NULL}, /* '8' */ - /* idx 124 */ {6, 57, NULL}, /* '9' */ - /* idx 125 */ {6, 57, NULL}, /* '9' */ - /* idx 126 */ {6, 57, NULL}, /* '9' */ - /* idx 127 */ {6, 57, NULL}, /* '9' */ - /* idx 128 */ {6, 61, NULL}, /* '=' */ - /* idx 129 */ {6, 61, NULL}, /* '=' */ - /* idx 130 */ {6, 61, NULL}, /* '=' */ - /* idx 131 */ {6, 61, NULL}, /* '=' */ - /* idx 132 */ {6, 65, NULL}, /* 'A' */ - /* idx 133 */ {6, 65, NULL}, /* 'A' */ - /* idx 134 */ {6, 65, NULL}, /* 'A' */ - /* idx 135 */ {6, 65, NULL}, /* 'A' */ - /* idx 136 */ {6, 95, NULL}, /* '_' */ - /* idx 137 */ {6, 95, NULL}, /* '_' */ - /* idx 138 */ {6, 95, NULL}, /* '_' */ - /* idx 139 */ {6, 95, NULL}, /* '_' */ - /* idx 140 */ {6, 98, NULL}, /* 'b' */ - /* idx 141 */ {6, 98, NULL}, /* 'b' */ - /* idx 142 */ {6, 98, NULL}, /* 'b' */ - /* idx 143 */ {6, 98, NULL}, /* 'b' */ - /* idx 144 */ {6, 100, NULL}, /* 'd' */ - /* idx 145 */ {6, 100, NULL}, /* 'd' */ - /* idx 146 */ {6, 100, NULL}, /* 'd' */ - /* idx 147 */ {6, 100, NULL}, /* 'd' */ - /* idx 148 */ {6, 102, NULL}, /* 'f' */ - /* idx 149 */ {6, 102, NULL}, /* 'f' */ - /* idx 150 */ {6, 102, NULL}, /* 'f' */ - /* idx 151 */ {6, 102, NULL}, /* 'f' */ - /* idx 152 */ {6, 103, NULL}, /* 'g' */ - /* idx 153 */ {6, 103, NULL}, /* 'g' */ - /* idx 154 */ {6, 103, NULL}, /* 'g' */ - /* idx 155 */ {6, 103, NULL}, /* 'g' */ - /* idx 156 */ {6, 104, NULL}, /* 'h' */ - /* idx 157 */ {6, 104, NULL}, /* 'h' */ - /* idx 158 */ {6, 104, NULL}, /* 'h' */ - /* idx 159 */ {6, 104, NULL}, /* 'h' */ - /* idx 160 */ {6, 108, NULL}, /* 'l' */ - /* idx 161 */ {6, 108, NULL}, /* 'l' */ - /* idx 162 */ {6, 108, NULL}, /* 'l' */ - /* idx 163 */ {6, 108, NULL}, /* 'l' */ - /* idx 164 */ {6, 109, NULL}, /* 'm' */ - /* idx 165 */ {6, 109, NULL}, /* 'm' */ - /* idx 166 */ {6, 109, NULL}, /* 'm' */ - /* idx 167 */ {6, 109, NULL}, /* 'm' */ - /* idx 168 */ {6, 110, NULL}, /* 'n' */ - /* idx 169 */ {6, 110, NULL}, /* 'n' */ - /* idx 170 */ {6, 110, NULL}, /* 'n' */ - /* idx 171 */ {6, 110, NULL}, /* 'n' */ - /* idx 172 */ {6, 112, NULL}, /* 'p' */ - /* idx 173 */ {6, 112, NULL}, /* 'p' */ - /* idx 174 */ {6, 112, NULL}, /* 'p' */ - /* idx 175 */ {6, 112, NULL}, /* 'p' */ - /* idx 176 */ {6, 114, NULL}, /* 'r' */ - /* idx 177 */ {6, 114, NULL}, /* 'r' */ - /* idx 178 */ {6, 114, NULL}, /* 'r' */ - /* idx 179 */ {6, 114, NULL}, /* 'r' */ - /* idx 180 */ {6, 117, NULL}, /* 'u' */ - /* idx 181 */ {6, 117, NULL}, /* 'u' */ - /* idx 182 */ {6, 117, NULL}, /* 'u' */ - /* idx 183 */ {6, 117, NULL}, /* 'u' */ - /* idx 184 */ {7, 58, NULL}, /* ':' */ - /* idx 185 */ {7, 58, NULL}, /* ':' */ - /* idx 186 */ {7, 66, NULL}, /* 'B' */ - /* idx 187 */ {7, 66, NULL}, /* 'B' */ - /* idx 188 */ {7, 67, NULL}, /* 'C' */ - /* idx 189 */ {7, 67, NULL}, /* 'C' */ - /* idx 190 */ {7, 68, NULL}, /* 'D' */ - /* idx 191 */ {7, 68, NULL}, /* 'D' */ - /* idx 192 */ {7, 69, NULL}, /* 'E' */ - /* idx 193 */ {7, 69, NULL}, /* 'E' */ - /* idx 194 */ {7, 70, NULL}, /* 'F' */ - /* idx 195 */ {7, 70, NULL}, /* 'F' */ - /* idx 196 */ {7, 71, NULL}, /* 'G' */ - /* idx 197 */ {7, 71, NULL}, /* 'G' */ - /* idx 198 */ {7, 72, NULL}, /* 'H' */ - /* idx 199 */ {7, 72, NULL}, /* 'H' */ - /* idx 200 */ {7, 73, NULL}, /* 'I' */ - /* idx 201 */ {7, 73, NULL}, /* 'I' */ - /* idx 202 */ {7, 74, NULL}, /* 'J' */ - /* idx 203 */ {7, 74, NULL}, /* 'J' */ - /* idx 204 */ {7, 75, NULL}, /* 'K' */ - /* idx 205 */ {7, 75, NULL}, /* 'K' */ - /* idx 206 */ {7, 76, NULL}, /* 'L' */ - /* idx 207 */ {7, 76, NULL}, /* 'L' */ - /* idx 208 */ {7, 77, NULL}, /* 'M' */ - /* idx 209 */ {7, 77, NULL}, /* 'M' */ - /* idx 210 */ {7, 78, NULL}, /* 'N' */ - /* idx 211 */ {7, 78, NULL}, /* 'N' */ - /* idx 212 */ {7, 79, NULL}, /* 'O' */ - /* idx 213 */ {7, 79, NULL}, /* 'O' */ - /* idx 214 */ {7, 80, NULL}, /* 'P' */ - /* idx 215 */ {7, 80, NULL}, /* 'P' */ - /* idx 216 */ {7, 81, NULL}, /* 'Q' */ - /* idx 217 */ {7, 81, NULL}, /* 'Q' */ - /* idx 218 */ {7, 82, NULL}, /* 'R' */ - /* idx 219 */ {7, 82, NULL}, /* 'R' */ - /* idx 220 */ {7, 83, NULL}, /* 'S' */ - /* idx 221 */ {7, 83, NULL}, /* 'S' */ - /* idx 222 */ {7, 84, NULL}, /* 'T' */ - /* idx 223 */ {7, 84, NULL}, /* 'T' */ - /* idx 224 */ {7, 85, NULL}, /* 'U' */ - /* idx 225 */ {7, 85, NULL}, /* 'U' */ - /* idx 226 */ {7, 86, NULL}, /* 'V' */ - /* idx 227 */ {7, 86, NULL}, /* 'V' */ - /* idx 228 */ {7, 87, NULL}, /* 'W' */ - /* idx 229 */ {7, 87, NULL}, /* 'W' */ - /* idx 230 */ {7, 89, NULL}, /* 'Y' */ - /* idx 231 */ {7, 89, NULL}, /* 'Y' */ - /* idx 232 */ {7, 106, NULL}, /* 'j' */ - /* idx 233 */ {7, 106, NULL}, /* 'j' */ - /* idx 234 */ {7, 107, NULL}, /* 'k' */ - /* idx 235 */ {7, 107, NULL}, /* 'k' */ - /* idx 236 */ {7, 113, NULL}, /* 'q' */ - /* idx 237 */ {7, 113, NULL}, /* 'q' */ - /* idx 238 */ {7, 118, NULL}, /* 'v' */ - /* idx 239 */ {7, 118, NULL}, /* 'v' */ - /* idx 240 */ {7, 119, NULL}, /* 'w' */ - /* idx 241 */ {7, 119, NULL}, /* 'w' */ - /* idx 242 */ {7, 120, NULL}, /* 'x' */ - /* idx 243 */ {7, 120, NULL}, /* 'x' */ - /* idx 244 */ {7, 121, NULL}, /* 'y' */ - /* idx 245 */ {7, 121, NULL}, /* 'y' */ - /* idx 246 */ {7, 122, NULL}, /* 'z' */ - /* idx 247 */ {7, 122, NULL}, /* 'z' */ - /* idx 248 */ {8, 38, NULL}, /* '&' */ - /* idx 249 */ {8, 42, NULL}, /* '*' */ - /* idx 250 */ {8, 44, NULL}, /* ',' */ - /* idx 251 */ {8, 59, NULL}, /* ';' */ - /* idx 252 */ {8, 88, NULL}, /* 'X' */ - /* idx 253 */ {8, 90, NULL}, /* 'Z' */ - /* idx 254 */ {8, 0, &byte1_pref0}, /* escape */ - /* idx 255 */ {8, 0, &byte1_pref1} /* escape */ -}; - -static struct stbl byte0 = { - 8, - byte0_array -}; diff --git a/bin/varnishtest/vtc_h2_hpack.c b/bin/varnishtest/vtc_h2_hpack.c index 52c8ee9cc..e52f16855 100644 --- a/bin/varnishtest/vtc_h2_hpack.c +++ b/bin/varnishtest/vtc_h2_hpack.c @@ -61,7 +61,7 @@ huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen) int l = 0; uint64_t pack = 0; unsigned pl = 0; /* pack length*/ - struct stbl *tbl = &byte0; + struct stbl *tbl = &tbl_0; struct ssym *sym; (void)nm; @@ -71,7 +71,7 @@ huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen) if (ilen == 0) { if (pl == 0 || (MASK(pack, pl) == (unsigned)((1U << pl) - 1U))) { - assert(tbl == &byte0); + assert(tbl == &tbl_0); return (l); } } @@ -102,7 +102,7 @@ huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen) continue; } str[l++] = sym->chr; - tbl = &byte0; + tbl = &tbl_0; } return (l); } From guillaume at varnish-software.com Mon Aug 6 02:07:09 2018 From: guillaume at varnish-software.com (Guillaume Quintard) Date: Mon, 6 Aug 2018 02:07:09 +0000 (UTC) Subject: [master] 38f4304ab Forgot one build dependency Message-ID: <20180806020709.D15D762700@lists.varnish-cache.org> commit 38f4304ab25805f58604462505dc57929cd1dbd4 Author: Guillaume Quintard Date: Sun Aug 5 19:06:19 2018 -0700 Forgot one build dependency diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 200f43394..fdb640df0 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -85,6 +85,7 @@ teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences awk -f $(srcdir)/gensequences $(srcdir)/sequences \ > $(builddir)/teken_state.h +vtc_h2_hpack.c: vtc_h2_dectbl.h vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h $(srcdir)/huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ mv $@_ $@ From phk at FreeBSD.org Mon Aug 6 06:30:18 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 6 Aug 2018 06:30:18 +0000 (UTC) Subject: [master] be7a7f991 Fix build Message-ID: <20180806063018.932336ED15@lists.varnish-cache.org> commit be7a7f9912699ca518499b3d22e43167438b11f6 Author: Poul-Henning Kamp Date: Mon Aug 6 06:29:05 2018 +0000 Fix build diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index fdb640df0..b34caa435 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -87,7 +87,8 @@ teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences vtc_h2_hpack.c: vtc_h2_dectbl.h vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h - $(srcdir)/huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ + $(PYTHON) $(srcdir)/huffman_gen.py \ + $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ mv $@_ $@ CLEANFILES = $(builddir)/teken_state.h From phk at FreeBSD.org Mon Aug 6 06:42:06 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 6 Aug 2018 06:42:06 +0000 (UTC) Subject: [master] 808472c5c Coverity spotted this as a resource-leak, even though it amounts to counting deck-chairs on the Titanic. Message-ID: <20180806064207.285C4904BE@lists.varnish-cache.org> commit 808472c5c276fa40f2acc24abb24b5cbcff83163 Author: Poul-Henning Kamp Date: Mon Aug 6 06:40:33 2018 +0000 Coverity spotted this as a resource-leak, even though it amounts to counting deck-chairs on the Titanic. diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index b9ad25a8e..dacb32260 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -1224,6 +1224,7 @@ vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt, "'%s' must be followed by BOOL," " found %s.\n", tokstr, vcc_utype(e2->fmt)); vcc_ErrWhere2(tl, tk, tl->t); + vcc_delete_expr(e2); return; } bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr); From phk at FreeBSD.org Mon Aug 6 16:01:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 6 Aug 2018 16:01:10 +0000 (UTC) Subject: [master] a84f5b180 Unbotch my refactoring of || and && handling in VCL expressions. Message-ID: <20180806160110.5CB609D3A1@lists.varnish-cache.org> commit a84f5b180cf976e642e48a2ab45413b98638e547 Author: Poul-Henning Kamp Date: Mon Aug 6 16:00:20 2018 +0000 Unbotch my refactoring of || and && handling in VCL expressions. Fixes: #2729 diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index dacb32260..39a01af38 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -1215,7 +1215,7 @@ vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt, while (tl->t->tok == ourtok) { vcc_NextToken(tl); tk = tl->t; - vcc_expr_not(tl, &e2, fmt); + up(tl, &e2, fmt); ERRCHK(tl); vcc_expr_tobool(tl, &e2); ERRCHK(tl); From phk at FreeBSD.org Mon Aug 6 17:25:09 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 6 Aug 2018 17:25:09 +0000 (UTC) Subject: [master] 610e0bbd4 Add regression test for #2729, but don't spend an entire test-case on it Message-ID: <20180806172509.BB74EA02AF@lists.varnish-cache.org> commit 610e0bbd40f33045a03b066636913dcf3c52afe7 Author: Poul-Henning Kamp Date: Mon Aug 6 17:24:04 2018 +0000 Add regression test for #2729, but don't spend an entire test-case on it diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index 60e1fb346..da563157f 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -137,6 +137,11 @@ varnish v1 -vcl { elseif (3) { } else if (4) { } else { } + + # regression test for #2729 + if (req.grace < 0s || req.grace < 1s && req.grace < 2s) { + return (pass); + } } } From phk at FreeBSD.org Mon Aug 6 17:29:06 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 6 Aug 2018 17:29:06 +0000 (UTC) Subject: [master] 771fc25a1 Make the output tab-space compliant Message-ID: <20180806172906.719E7A055E@lists.varnish-cache.org> commit 771fc25a18f9657d0a95d7be01895c313e28aa4d Author: Poul-Henning Kamp Date: Mon Aug 6 17:27:52 2018 +0000 Make the output tab-space compliant diff --git a/bin/varnishtest/huffman_gen.py b/bin/varnishtest/huffman_gen.py index 1486bd41d..00ff16fe6 100755 --- a/bin/varnishtest/huffman_gen.py +++ b/bin/varnishtest/huffman_gen.py @@ -85,7 +85,7 @@ for pfx in sorted(tbls.keys(), reverse=True): for s in tbl: for j in range(2 ** (msl - s.vall)): print(" {} {{{}, {:3d}, {}}},".format( - " "*13 if j else "/* idx {:3d} */".format(s.val + j), + "\t " if j else "/* idx {:3d} */".format(s.val + j), s.vall, s.chr % 256, s.esc if s.esc else "NULL")) print('''}}; From geoff at uplex.de Tue Aug 7 08:42:07 2018 From: geoff at uplex.de (Geoff Simmons) Date: Tue, 7 Aug 2018 08:42:07 +0000 (UTC) Subject: [master] 23386a454 Add std.fnmatch() Message-ID: <20180807084208.15CC39C5C@lists.varnish-cache.org> commit 23386a454284a62781799f484684048be866608b Author: Geoff Simmons Date: Fri Jul 27 17:26:16 2018 +0200 Add std.fnmatch() Closes: #2737 diff --git a/bin/varnishtest/tests/m00050.vtc b/bin/varnishtest/tests/m00050.vtc new file mode 100644 index 000000000..a6578a6bd --- /dev/null +++ b/bin/varnishtest/tests/m00050.vtc @@ -0,0 +1,188 @@ +varnishtest "std.fnmatch()" + +varnish v1 -vcl { + import std; + backend b { .host = "${bad_ip}"; } + + sub vcl_recv { + return (synth(200)); + } + + sub vcl_synth { + set resp.http.Match + = std.fnmatch(req.http.Pattern, req.http.Subject); + set resp.http.Match-Nopathname = std.fnmatch(req.http.Pattern, + req.http.Subject, + pathname=false); + set resp.http.Match-Noescape = std.fnmatch(req.http.Pattern, + req.http.Subject, + noescape=true); + set resp.http.Match-Period = std.fnmatch(req.http.Pattern, + req.http.Subject, + period=true); + } +} -start + +client c1 { + txreq -hdr "Pattern: /foo/" -hdr "Subject: /foo/" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/" -hdr "Subject: /bar/" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/*" -hdr "Subject: /foo/bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/bar/*" -hdr "Subject: /foo/bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/?" -hdr "Subject: /foo/b" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/?" -hdr "Subject: /foo/bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[a-z]" -hdr "Subject: /foo/b" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[a-z]" -hdr "Subject: /foo/B" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[!a-z]" -hdr "Subject: /foo/B" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/*/quux" -hdr "Subject: /foo/bar/baz/quux" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == "true" + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/?/bar" -hdr "Subject: /foo///bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == "true" + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[a/b]/bar" -hdr "Subject: /foo///bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == "true" + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr {Pattern: \\foo} -hdr {Subject: \foo} + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == "false" + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: *foo" -hdr "Subject: .foo" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == "false" + + txreq -hdr "Pattern: /*foo" -hdr "Subject: /.foo" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == "false" +} -run + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + import std; + + sub vcl_deliver { + set resp.http.Match + = std.fnmatch(req.http.Pattern, req.http.Subject); + } +} + +client c1 { + txreq -hdr "Pattern: /foo/" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" { + expect 0 * Begin + expect * = VCL_Error {^std\.fnmatch\(\): subject is NULL$} + expect * = End +} -run + +logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { + expect 0 * Begin + expect * = VCL_Error {^std\.fnmatch\(\): pattern is NULL$} + expect * = End +} -start + +client c1 { + txreq -hdr "Subject: /foo/" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -wait diff --git a/configure.ac b/configure.ac index 6e6734c3e..3a45477b3 100644 --- a/configure.ac +++ b/configure.ac @@ -208,6 +208,7 @@ AC_CHECK_HEADERS([sys/vfs.h]) AC_CHECK_HEADERS([endian.h]) AC_CHECK_HEADERS([pthread_np.h], [], [], [#include ]) AC_CHECK_HEADERS([priv.h]) +AC_CHECK_HEADERS([fnmatch.h], [], [AC_MSG_ERROR([fnmatch.h is required])]) # Checks for library functions. _VARNISH_CHECK_EXPLICIT_BZERO @@ -218,6 +219,7 @@ AC_CHECK_FUNCS([closefrom]) AC_CHECK_FUNCS([sigaltstack]) AC_CHECK_FUNCS([getpeereid]) AC_CHECK_FUNCS([getpeerucred]) +AC_CHECK_FUNCS([fnmatch], [], [AC_MSG_ERROR([fnmatch(3) is required])]) save_LIBS="${LIBS}" LIBS="${PTHREAD_LIBS}" diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index c8305ae9d..c46d24156 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -361,8 +361,70 @@ $Function BOOL syntax(REAL) Description Returns the true if VCL version is at least REAL. +$Function BOOL fnmatch(STRING pattern, STRING subject, BOOL pathname=1, + BOOL noescape=0, BOOL period=0) + +Description + Shell-style pattern matching; returns `true` if *subject* + matches *pattern*, where *pattern* may contain wildcard + characters such as \* or ?. + + The match is executed by the implementation of `fnmatch(3)` on + your system. The rules for pattern matching on most systems + include the following: + + * \* matches any sequence of characters + + * ? matches a single character + + * a bracket expresion such as [abc] or [!0-9] is interpreted + as a character class according to the rules of basic regular + expressions (*not* PCRE regexen), except that ! is used for + character class negation instead of ^. + + If *pathname* is `true`, then the forward slash character / is + only matched literally, and never matches \*, ? or a bracket + expression. Otherwise, / may match one of those patterns. By + default, *pathname* is `true`. + + If *noescape* is `true`, then the backslash character \\ is + matched as an ordinary character. Otherwise, \\ is an escape + character, and matches the character that follows it in the + `pattern`. For example, \\\\ matches \\ when *noescape* is + `true`, and \\\\ when `false`. By default, *noescape* is + `false`. + + If *period* is `true`, then a leading period character . only + matches literally, and never matches \*, ? or a bracket + expression. A period is leading if it is the first character + in `subject`; if *pathname* is also `true`, then a period that + immediately follows a / is also leading (as in "/."). By + default, *period* is `false`. + + `fnmatch()` invokes VCL failure and returns `false` if either + of *pattern* or *subject* is NULL -- for example, if an unset + header is specified. + +Examples + | # Matches URLs such as /foo/bar and /foo/bar/baz + | if (std.fnmatch("/foo/\*", req.url)) { ... } + | + | # Matches /foo/bar/quux, but not /foo/bar/baz/quux + | if (std.fnmatch("/foo/\*/quux", req.url)) { ... } + | + | # Matches /foo/bar/quux and /foo/bar/baz/quux + | if (std.fnmatch("/foo/\*/quux", req.url, pathname=false)) { ... } + | + | # Matches /foo/bar, /foo/car and /foo/far + | if (std.fnmatch("/foo/?ar", req.url)) { ... } + | + | # Matches /foo/ followed by a non-digit + | if (std.fnmatch("/foo/[!0-9]", req.url)) { ... } + + SEE ALSO ======== * :ref:`varnishd(1)` * :ref:`vsl(7)` +* `fnmatch(3)` diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 4be62ae7e..03a39453e 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "cache/cache.h" @@ -302,3 +303,28 @@ vmod_syntax(VRT_CTX, VCL_REAL r) */ return (round(r * 10) <= ctx->syntax); } + +VCL_BOOL v_matchproto_(td_std_fnmatch) +vmod_fnmatch(VRT_CTX, VCL_STRING pattern, VCL_STRING subject, + VCL_BOOL pathname, VCL_BOOL noescape, VCL_BOOL period) +{ + int flags = 0; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (pattern == NULL) { + VRT_fail(ctx, "std.fnmatch(): pattern is NULL"); + return (0); + } + if (subject == NULL) { + VRT_fail(ctx, "std.fnmatch(): subject is NULL"); + return (0); + } + + if (pathname) + flags |= FNM_PATHNAME; + if (noescape) + flags |= FNM_NOESCAPE; + if (period) + flags |= FNM_PERIOD; + return (fnmatch(pattern, subject, flags) != FNM_NOMATCH); +} From phk at FreeBSD.org Tue Aug 7 09:39:09 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 7 Aug 2018 09:39:09 +0000 (UTC) Subject: [master] 48d013f6d Expand macros in HAproxy config files. Message-ID: <20180807093909.9BB0061AAC@lists.varnish-cache.org> commit 48d013f6df8f58543d6501993bea783b8bf807af Author: Poul-Henning Kamp Date: Tue Aug 7 09:38:04 2018 +0000 Expand macros in HAproxy config files. Submitted by: Frederic Lecaille diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 2de165031..a3e89c713 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -435,7 +435,7 @@ haproxy_check_conf(struct haproxy *h, const char *expect) static void haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) { - struct vsb *vsb, *vsb2; + struct vsb *vsb, *vsb2, *vsb3; vsb = VSB_new_auto(); AN(vsb); @@ -454,14 +454,18 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) AZ(haproxy_build_backends(h, VSB_data(vsb))); + vsb3 = macro_expand(h->vl, VSB_data(vsb)); + AN(vsb3); + if (VFIL_writefile(h->workdir, h->cfg_fn, - VSB_data(vsb), VSB_len(vsb)) != 0) + VSB_data(vsb3), VSB_len(vsb3)) != 0) vtc_fatal(h->vl, "failed to write haproxy configuration file: %s (%d)", strerror(errno), errno); - vtc_dump(h->vl, 4, "conf", VSB_data(vsb), VSB_len(vsb)); + vtc_dump(h->vl, 4, "conf", VSB_data(vsb3), VSB_len(vsb3)); + VSB_destroy(&vsb3); VSB_destroy(&vsb2); VSB_destroy(&vsb); } From geoff at uplex.de Tue Aug 7 10:48:06 2018 From: geoff at uplex.de (Geoff Simmons) Date: Tue, 7 Aug 2018 10:48:06 +0000 (UTC) Subject: [master] f5506c270 Typo Message-ID: <20180807104806.B1F7A62FB3@lists.varnish-cache.org> commit f5506c27049a3c0795f83a5c0ae0e84fd760a20c Author: Geoff Simmons Date: Tue Aug 7 12:46:46 2018 +0200 Typo diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index c46d24156..87bcca003 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -377,7 +377,7 @@ Description * ? matches a single character - * a bracket expresion such as [abc] or [!0-9] is interpreted + * a bracket expression such as [abc] or [!0-9] is interpreted as a character class according to the rules of basic regular expressions (*not* PCRE regexen), except that ! is used for character class negation instead of ^. From geoff at uplex.de Tue Aug 7 12:15:12 2018 From: geoff at uplex.de (Geoff Simmons) Date: Tue, 7 Aug 2018 12:15:12 +0000 (UTC) Subject: [master] 738311611 Example fix. Message-ID: <20180807121512.9262665BB3@lists.varnish-cache.org> commit 7383116117b1b141dd4ad82b163b2dcdab759a47 Author: Geoff Simmons Date: Tue Aug 7 14:14:35 2018 +0200 Example fix. diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index 87bcca003..c30172ed1 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -406,9 +406,12 @@ Description header is specified. Examples - | # Matches URLs such as /foo/bar and /foo/bar/baz + | # Matches URLs such as /foo/bar and /foo/baz | if (std.fnmatch("/foo/\*", req.url)) { ... } | + | # Matches URLs such as /foo/bar/baz and /foo/baz/quux + | if (std.fnmatch("/foo/\*/\*", bereq.url)) { ... } + | | # Matches /foo/bar/quux, but not /foo/bar/baz/quux | if (std.fnmatch("/foo/\*/quux", req.url)) { ... } | From phk at FreeBSD.org Mon Aug 13 06:56:09 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2018 06:56:09 +0000 (UTC) Subject: [master] 13bae75e0 Report STRANDS as STRING in documentation. Message-ID: <20180813065609.EF4DA92B08@lists.varnish-cache.org> commit 13bae75e0af23528aec7eaefacd5b295bf79fcab Author: Poul-Henning Kamp Date: Mon Aug 13 06:55:01 2018 +0000 Report STRANDS as STRING in documentation. Start pylinting while here anyway. diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index 8937aefac..669450fb7 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -86,14 +86,14 @@ CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h \\ ''' -privs = { +PRIVS = { 'PRIV_CALL': "struct vmod_priv *", 'PRIV_VCL': "struct vmod_priv *", 'PRIV_TASK': "struct vmod_priv *", 'PRIV_TOP': "struct vmod_priv *", } -ctypes = { +CTYPES = { 'ACL': "VCL_ACL", 'BACKEND': "VCL_BACKEND", 'BLOB': "VCL_BLOB", @@ -116,7 +116,7 @@ ctypes = { 'VOID': "VCL_VOID", } -ctypes.update(privs) +CTYPES.update(PRIVS) ####################################################################### @@ -162,7 +162,7 @@ def lwrap(s, width=64): ll.append(p + s[:y + 1]) s = s[y + 1:].lstrip() p = " " - if len(s) > 0: + if s: ll.append(p + s) return "\n".join(ll) + "\n" @@ -182,19 +182,19 @@ def fmt_cstruct(fo, mn, x): inputline = None -def err(str, warn=True): +def err(txt, warn=True): if inputline is not None: print("While parsing line:\n\t", inputline) if opts.strict or not warn: - print("ERROR: " + str, file=sys.stderr) + print("ERROR: " + txt, file=sys.stderr) exit(1) else: - print("WARNING: " + str, file=sys.stderr) + print("WARNING: " + txt, file=sys.stderr) ####################################################################### -class ctype(object): +class CType(object): def __init__(self, wl, enums): self.nm = None self.defval = None @@ -202,10 +202,10 @@ class ctype(object): self.opt = False self.vt = wl.pop(0) - self.ct = ctypes.get(self.vt) + self.ct = CTYPES.get(self.vt) if self.ct is None: err("Expected type got '%s'" % self.vt, warn=False) - if len(wl) > 0 and wl[0] == "{": + if wl and wl[0] == "{": if self.vt != "ENUM": err("Only ENUMs take {...} specs", warn=False) self.add_spec(wl, enums) @@ -230,7 +230,7 @@ class ctype(object): x = x[1:-1] elif x[0] == "'" and x[-1] == "'": x = x[1:-1] - assert len(x) > 0 + assert x self.spec.append(x) enums[x] = True w = wl.pop(0) @@ -239,14 +239,14 @@ class ctype(object): assert w == "," def vcl(self): - if self.vt == "STRING_LIST": + if self.vt in ("STRING_LIST", "STRAND"): return "STRING" if self.spec is None: return self.vt return self.vt + " {" + ", ".join(self.spec) + "}" def synopsis(self): - if self.vt == "STRING_LIST": + if self.vt in ("STRING_LIST", "STRAND"): return "STRING" return self.vt @@ -258,7 +258,7 @@ class ctype(object): ####################################################################### -class arg(ctype): +class arg(CType): def __init__(self, wl, argnames, enums, end): super(arg, self).__init__(wl, enums) @@ -299,6 +299,7 @@ class arg(ctype): def lex(l): wl = [] s = 0 + assert l for i in range(len(l)): c = l[i] @@ -342,7 +343,7 @@ def lex(l): ####################################################################### -class prototype(object): +class ProtoType(object): def __init__(self, st, retval=True, prefix=""): self.st = st self.obj = None @@ -351,9 +352,9 @@ class prototype(object): wl = lex(st.line[1]) if retval: - self.retval = ctype(wl, st.vcc.enums) + self.retval = CType(wl, st.vcc.enums) else: - self.retval = ctype(['VOID'], st.vcc.enums) + self.retval = CType(['VOID'], st.vcc.enums) self.bname = wl.pop(0) if not re.match("^[a-zA-Z.][a-zA-Z0-9_]*$", self.bname): @@ -376,12 +377,12 @@ class prototype(object): names = {} n = 0 - while len(wl) > 0: + while wl: n += 1 x = wl.pop(0) if x != ',': err("Expected ',' found '%s'" % x, warn=False) - if len(wl) == 0: + if not wl: break if wl[0] == '[': wl.pop(0) @@ -420,7 +421,7 @@ class prototype(object): t = i.synopsis() else: t = i.vcl() - if t in privs: + if t in PRIVS: continue if i.nm is not None: t += " " + i.nm @@ -528,9 +529,9 @@ class prototype(object): class stanza(object): def __init__(self, l0, doc, vcc): self.line = l0 - while len(doc) > 0 and doc[0] == '': + while doc and doc[0] == '': doc.pop(0) - while len(doc) > 0 and doc[-1] == '': + while doc and doc[-1] == '': doc.pop(-1) self.doc = doc self.vcc = vcc @@ -668,7 +669,7 @@ class s_event(stanza): self.vcc.contents.append(self) def rstfile(self, fo, man): - if len(self.doc) != 0: + if self.doc: err("Not emitting .RST for $Event %s\n" % self.event_func) @@ -684,14 +685,14 @@ class s_event(stanza): def json(self, jl): jl.append([ - "$EVENT", - "Vmod_%s_Func._event" % self.vcc.modname + "$EVENT", + "Vmod_%s_Func._event" % self.vcc.modname ]) class s_function(stanza): def parse(self): - self.proto = prototype(self) + self.proto = ProtoType(self) self.rstlbl = "func_" + self.proto.name self.vcc.contents.append(self) @@ -711,7 +712,7 @@ class s_function(stanza): class s_object(stanza): def parse(self): - self.proto = prototype(self, retval=False) + self.proto = ProtoType(self, retval=False) self.proto.obj = "x" + self.proto.name self.init = copy.copy(self.proto) @@ -799,7 +800,7 @@ class s_method(stanza): p = self.vcc.contents[-1] assert type(p) == s_object self.pfx = p.proto.name - self.proto = prototype(self, prefix=self.pfx) + self.proto = ProtoType(self, prefix=self.pfx) if not self.proto.bname.startswith("."): err("$Method %s: Method names need to start with . (dot)" % self.proto.bname, warn=False) @@ -820,7 +821,7 @@ class s_method(stanza): ####################################################################### -dispatch = { +DISPATCH = { "Module": s_module, "Prefix": s_prefix, "ABI": s_abi, @@ -844,6 +845,7 @@ class vcc(object): self.enums = {} self.strict_abi = True self.auto_synopsis = True + self.modname = None def openfile(self, fn): self.commit_files.append(fn) @@ -858,11 +860,11 @@ class vcc(object): a = "\n" + open(self.inputfile, "r").read() s = a.split("\n$") self.copyright = s.pop(0).strip() - while len(s): + while s: ss = re.split('\n([^\t ])', s.pop(0), maxsplit=1) c = ss[0].split() d = "".join(ss[1:]) - m = dispatch.get(c[0]) + m = DISPATCH.get(c[0]) if m is None: err("Unknown stanze $%s" % ss[:i]) m([c[0], " ".join(c[1:])], d.split('\n'), self) @@ -891,7 +893,7 @@ class vcc(object): for i in self.contents: i.rstfile(fo, man) - if len(self.copyright): + if self.copyright: self.rst_copyright(fo) fo.close() @@ -1075,7 +1077,7 @@ if __name__ == "__main__": help='Output file prefix (default: "vcc_if")') oparser.add_option('-w', '--rstdir', metavar="directory", default='.', help='Where to save the generated RST files ' + - '(default: ".")') + '(default: ".")') oparser.add_option('', '--runtests', action='store_true', default=False, dest="runtests", help=optparse.SUPPRESS_HELP) (opts, args) = oparser.parse_args() From phk at FreeBSD.org Mon Aug 13 07:12:05 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2018 07:12:05 +0000 (UTC) Subject: [master] 50048822a Respect the end of input buffer when skipping the second [CR]LF after the headers. Message-ID: <20180813071205.D12DC93172@lists.varnish-cache.org> commit 50048822ae88fcfe4202e9cdaf5f9bc6f65084f9 Author: Poul-Henning Kamp Date: Mon Aug 13 07:10:40 2018 +0000 Respect the end of input buffer when skipping the second [CR]LF after the headers. Fixes: #2731 diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index ac1a2a86e..dd81863d3 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -206,8 +206,11 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, return (400); } } - if (p < htc->rxbuf_e) - p += vct_skipcrlf(p); + /* We cannot use vct_skipcrlf() we have to respect rxbuf_e */ + if (p+2 <= htc->rxbuf_e && p[0] == '\r' && p[1] == '\n') + p += 2; + else if (p+1 <= htc->rxbuf_e && p[0] == '\n') + p += 1; HTC_RxPipeline(htc, p); htc->rxbuf_e = p; return (0); From geoff at uplex.de Mon Aug 13 08:24:06 2018 From: geoff at uplex.de (Geoff Simmons) Date: Mon, 13 Aug 2018 08:24:06 +0000 (UTC) Subject: [master] ff56b8e32 Add VRT functions for STRANDS. Message-ID: <20180813082406.F21AC946FE@lists.varnish-cache.org> commit ff56b8e3262085e10dcc428211f4b2b7090c6332 Author: Geoff Simmons Date: Thu Jul 19 17:03:30 2018 +0200 Add VRT functions for STRANDS. Re-implementations of the current functions for STRING_LIST. Closes #2733 diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 8765c64fa..200ec18d0 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -339,6 +339,117 @@ VRT_CollectString(VRT_CTX, const char *p, ...) return (b); } +/*-------------------------------------------------------------------- + * Collapse STRANDS into the space provided, or return NULL + */ + +char * +VRT_Strands(char *d, size_t dl, VCL_STRANDS s) +{ + char *b; + const char *e; + unsigned x; + + AN(d); + AN(s); + b = d; + e = b + dl; + for (int i = 0; i < s->n && b < e; i++) + if (s->p[i] != NULL && *s->p[i] != '\0') { + x = strlen(s->p[i]); + if (b + x < e) + memcpy(b, s->p[i], x); + b += x; + } + if (b >= e) + return (NULL); + *b++ = '\0'; + return (b); +} + +/*-------------------------------------------------------------------- + * Copy and merge STRANDS into a workspace. + */ + +VCL_STRING +VRT_StrandsWS(struct ws *ws, const char *h, VCL_STRANDS s) +{ + char *b; + const char *q = NULL, *e; + VCL_STRING r; + unsigned u, x; + int i; + + AN(s); + u = WS_Reserve(ws, 0); + + for (i = 0; i < s->n; i++) + if (s->p[i] != NULL && *s->p[i] != '\0') { + q = s->p[i]; + break; + } + + if (h != NULL && q == NULL && WS_Inside(ws, h, NULL)) { + WS_Release(ws, 0); + return (h); + } + + if (h == NULL) { + if (q == NULL) { + WS_Release(ws, 0); + return (""); + } + if (WS_Inside(ws, q, NULL)) { + for (i++; i < s->n; i++) + if (s->p[i] != NULL && *s->p[i] != '\0') + break; + if (i == s->n) { + WS_Release(ws, 0); + return (q); + } + } + } + + b = WS_Front(ws); + e = b + u; + + if (h != NULL) { + x = strlen(h); + if (b + x < e) + memcpy(b, h, x); + b += x; + if (b < e) + *b = ' '; + b++; + } + r = VRT_Strands(b, e > b ? e - b : 0, s); + if (r == NULL || r == e) { + WS_MarkOverflow(ws); + WS_Release(ws, 0); + return (NULL); + } + b = WS_Front(ws); + WS_Release(ws, r - b); + return (b); +} + +/*-------------------------------------------------------------------- + * Copy and merge STRANDS on the current workspace + */ + +VCL_STRING +VRT_CollectStrands(VRT_CTX, VCL_STRANDS s) +{ + const char *b; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); + b = VRT_StrandsWS(ctx->ws, NULL, s); + if (b == NULL) + VRT_fail(ctx, "Workspace overflow"); + return (b); +} + /*--------------------------------------------------------------------*/ VCL_VOID diff --git a/bin/varnishtest/tests/v00058.vtc b/bin/varnishtest/tests/v00058.vtc new file mode 100644 index 000000000..d76e3d397 --- /dev/null +++ b/bin/varnishtest/tests/v00058.vtc @@ -0,0 +1,167 @@ +varnishtest "Test VRT STRANDS functions" + +varnish v1 -arg "-i foobar" -vcl { + import debug; + backend b { .host = "${bad_ip}"; } + + sub vcl_init { + # tests VRT_Strands() + new c = debug.concat(server.identity + server.hostname + now); + new e = debug.concat("" + server.identity + ""); + } + + sub vcl_recv { + return (synth(200)); + } + + sub vcl_synth { + set resp.http.C = c.get(); + set resp.http.E = e.get(); + + set req.http.Foo = "foo"; + set req.http.Bar = "bar"; + set req.http.Baz = "baz"; + + # test VRT_StrandsWS() + set resp.http.Concat-1 + = debug.concatenate(req.http.Foo + req.http.Bar + + req.http.Baz); + set resp.http.Concat-2 + = debug.concatenate("" + req.http.Unset + req.http.Foo + + req.http.Unset + "" + + req.http.Bar + "" + + req.http.Unset + "" + + req.http.Baz + "" + + req.http.Unset); + set resp.http.Concat-3 + = debug.concatenate(req.http.Foo + req.http.Unset + ""); + set resp.http.Concat-4 + = debug.concatenate(req.http.Unset + "" + req.http.Foo); + set resp.http.Concat-5 + = debug.concatenate(req.http.Foo + req.http.Unset + + req.http.Bar); + set resp.http.Concat-6 = debug.concatenate(req.http.Foo); + set resp.http.Concat-7 = debug.concatenate(req.http.Unset); + + # test VRT_StrandsCollect() + set resp.http.Collect-1 + = debug.collect(req.http.Foo + req.http.Bar + + req.http.Baz); + set resp.http.Collect-2 + = debug.collect("" + req.http.Unset + req.http.Foo + + req.http.Unset + "" + req.http.Bar + + "" + req.http.Unset + "" + + req.http.Baz + "" + req.http.Unset); + set resp.http.Collect-3 + = debug.collect(req.http.Foo + req.http.Unset + ""); + set resp.http.Collect-4 + = debug.collect(req.http.Unset + "" + req.http.Foo); + set resp.http.Collect-5 + = debug.collect(req.http.Foo + req.http.Unset + + req.http.Bar); + set resp.http.Collect-6 = debug.collect(req.http.Foo); + set resp.http.Collect-7 = debug.collect(req.http.Unset); + + # test a STRANDS version of VRT_SetHdr() + debug.sethdr(resp.http.Hdr-1, req.http.Foo + req.http.Bar + + req.http.Baz); + debug.sethdr(resp.http.Hdr-2, + "" + req.http.Unset + req.http.Foo + + req.http.Unset + "" + req.http.Bar + "" + + req.http.Unset + "" + req.http.Baz + "" + + req.http.Unset); + debug.sethdr(resp.http.Hdr-3, + req.http.Foo + req.http.Unset + ""); + debug.sethdr(resp.http.Hdr-4, + req.http.Unset + "" + req.http.Foo); + debug.sethdr(resp.http.Hdr-5, + req.http.Foo + req.http.Unset + req.http.Bar); + debug.sethdr(resp.http.Hdr-6, req.http.Foo); + debug.sethdr(resp.http.Hdr-7, req.http.Unset); + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.C ~ "^foobar" + expect resp.http.E == "foobar" + expect resp.http.Concat-1 == "foobarbaz" + expect resp.http.Concat-2 == "foobarbaz" + expect resp.http.Concat-3 == "foo" + expect resp.http.Concat-4 == "foo" + expect resp.http.Concat-5 == "foobar" + expect resp.http.Concat-6 == "foo" + expect resp.http.Concat-7 == "" + expect resp.http.Collect-1 == "foobarbaz" + expect resp.http.Collect-2 == "foobarbaz" + expect resp.http.Collect-3 == "foo" + expect resp.http.Collect-4 == "foo" + expect resp.http.Collect-5 == "foobar" + expect resp.http.Collect-6 == "foo" + expect resp.http.Collect-7 == "" + expect resp.http.Hdr-1 == "foobarbaz" + expect resp.http.Hdr-2 == "foobarbaz" + expect resp.http.Hdr-3 == "foo" + expect resp.http.Hdr-4 == "foo" + expect resp.http.Hdr-5 == "foobar" + expect resp.http.Hdr-6 == "foo" + expect resp.http.Hdr-7 == "" +} -run + +# out of workspace +server s1 { + rxreq + expect req.http.Foo == "foo" + expect req.http.Bar == "bar" + expect req.http.Baz == "baz" + expect req.http.Quux == "quux" + expect req.http.Result == + txresp +} -start + +varnish v1 -vcl+backend { + import debug; + import vtc; + + sub vcl_recv { + set req.http.Foo = "foo"; + set req.http.Bar = "bar"; + set req.http.Baz = "baz"; + set req.http.Quux = "quux"; + + vtc.workspace_alloc(client, -12); + + if (req.url == "/1") { + # VRT_StrandsWS() marks the WS as overflowed, + # returns NULL, but does not invoke VCL failure. + # Out-of-workspace doesn't happen until delivery. + set req.http.Result + = debug.concatenate(req.http.Foo + req.http.Bar + + req.http.Baz + + req.http.Quux); + } + elsif (req.url == "/2") { + # VRT_CollectStrands() invokes VCL failure. + set req.http.Result + = debug.collect(req.http.Foo + req.http.Bar + + req.http.Baz + + req.http.Quux); + } + } +} + +client c1 { + txreq -url "/1" + rxresp + expect resp.status == 500 + expect resp.reason == "Internal Server Error" +} -run + +client c1 { + txreq -url "/2" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run diff --git a/include/vrt.h b/include/vrt.h index d4c97c346..4c41976fd 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -53,6 +53,10 @@ * * * TRUNK (2018-09-15) + * VRT_Strands() added + * VRT_StrandsWS() added + * VRT_CollectStrands() added + * VRT_STRANDS_string() removed from vrt.h (never implemented) * VRT_Healthy() changed prototype * 7.0 (2018-03-15) * lots of stuff moved from cache.h to cache_varnishd.h @@ -502,6 +506,9 @@ VCL_STEVEDORE VRT_stevedore(const char *nm); VCL_STRANDS VRT_BundleStrands(int, struct strands *, char const **, const char *f, ...); int VRT_CompareStrands(VCL_STRANDS a, VCL_STRANDS b); +char *VRT_Strands(char *, size_t, VCL_STRANDS); +VCL_STRING VRT_StrandsWS(struct ws *, const char *, VCL_STRANDS); +VCL_STRING VRT_CollectStrands(VRT_CTX, VCL_STRANDS); VCL_STRING VRT_BACKEND_string(VCL_BACKEND); VCL_STRING VRT_BOOL_string(VCL_BOOL); @@ -510,7 +517,6 @@ VCL_STRING VRT_INT_string(VRT_CTX, VCL_INT); VCL_STRING VRT_IP_string(VRT_CTX, VCL_IP); VCL_STRING VRT_REAL_string(VRT_CTX, VCL_REAL); VCL_STRING VRT_STEVEDORE_string(VCL_STEVEDORE); -VCL_STRING VRT_STRANDS_string(VCL_STRANDS); VCL_STRING VRT_TIME_string(VRT_CTX, VCL_TIME); #ifdef va_start // XXX: hackish diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc index 3e6b06108..0ab33501f 100644 --- a/lib/libvmod_debug/vmod.vcc +++ b/lib/libvmod_debug/vmod.vcc @@ -177,3 +177,26 @@ Update counter $Function VOID vsc_destroy() Remove a vsc + +$Object concat(STRANDS) + +Create an object that returns the string formed by concatenating the +given strings. + +$Method STRING .get() + +Return the string formed from the concatenation in the constructor. + +$Function STRING concatenate(STRANDS) + +Return the string formed by concatenating the given strings. +(Uses VRT_StrandsWS().) + +$Function STRING collect(STRANDS) + +Return the string formed by concatenating the given strings. +(Uses VRT_CollectStrands().) + +$Function VOID sethdr(HEADER, STRANDS) + +Set the given header with the concatenation of the given strings. diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c index 5c2661efe..5d84206fa 100644 --- a/lib/libvmod_debug/vmod_debug.c +++ b/lib/libvmod_debug/vmod_debug.c @@ -430,3 +430,110 @@ xyzzy_vsc_destroy(VRT_CTX) vsc = NULL; AZ(pthread_mutex_unlock(&vsc_mtx)); } + +struct xyzzy_debug_concat { + unsigned magic; +#define CONCAT_MAGIC 0x6b746493 + VCL_STRING s; +}; + +VCL_VOID +xyzzy_concat__init(VRT_CTX, struct xyzzy_debug_concat **concatp, + const char *vcl_name, VCL_STRANDS s) +{ + struct xyzzy_debug_concat *concat; + size_t sz = 0; + char *p; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + AN(concatp); + AZ(*concatp); + AN(vcl_name); + + ALLOC_OBJ(concat, CONCAT_MAGIC); + AN(concat); + *concatp = concat; + + for (int i = 0; i < s->n; i++) + if (s->p[i] != NULL) + sz += strlen(s->p[i]); + p = malloc(sz + 1); + AN(p); + (void)VRT_Strands(p, sz + 1, s); + concat->s = p; +} + +VCL_VOID +xyzzy_concat__fini(struct xyzzy_debug_concat **concatp) +{ + struct xyzzy_debug_concat *concat; + void *p; + + if (concatp == NULL || *concatp == NULL) + return; + CHECK_OBJ(*concatp, CONCAT_MAGIC); + concat = *concatp; + *concatp = NULL; + p = TRUST_ME(concat->s); + free(p); + FREE_OBJ(concat); +} + +VCL_STRING +xyzzy_concat_get(VRT_CTX, struct xyzzy_debug_concat *concat) +{ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(concat, CONCAT_MAGIC); + return (concat->s); +} + +VCL_STRING +xyzzy_concatenate(VRT_CTX, VCL_STRANDS s) +{ + VCL_STRING r; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + r = VRT_StrandsWS(ctx->ws, NULL, s); + if (r != NULL && *r != '\0') + WS_Assert_Allocated(ctx->ws, r, strlen(r) + 1); + return (r); +} + +VCL_STRING +xyzzy_collect(VRT_CTX, VCL_STRANDS s) +{ + VCL_STRING r; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + r = VRT_CollectStrands(ctx, s); + if (r != NULL && *r != '\0') + WS_Assert_Allocated(ctx->ws, r, strlen(r) + 1); + return (r); +} + +/* cf. VRT_SetHdr() */ +VCL_VOID +xyzzy_sethdr(VRT_CTX, VCL_HEADER hs, VCL_STRANDS s) +{ + struct http *hp; + const char *b; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + AN(hs); + AN(hs->what); + hp = VRT_selecthttp(ctx, hs->where); + CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + if (s->n == 0) { + http_Unset(hp, hs->what); + } else { + b = VRT_StrandsWS(hp->ws, hs->what + 1, s); + if (b == NULL) { + VSLb(ctx->vsl, SLT_LostHeader, "%s", hs->what + 1); + } else { + if (*b != '\0') + WS_Assert_Allocated(hp->ws, b, strlen(b) + 1); + http_Unset(hp, hs->what); + http_SetHeader(hp, b); + } + } +} From geoff at uplex.de Mon Aug 13 08:51:08 2018 From: geoff at uplex.de (Geoff Simmons) Date: Mon, 13 Aug 2018 08:51:08 +0000 (UTC) Subject: [master] 23a6efe36 Make the out-of-workspace tests for STRANDS robust for 32-bit. Message-ID: <20180813085108.6CF5B94FE1@lists.varnish-cache.org> commit 23a6efe3624bd9297f16a4be11b7ef7f4a00efb7 Author: Geoff Simmons Date: Mon Aug 13 10:49:45 2018 +0200 Make the out-of-workspace tests for STRANDS robust for 32-bit. diff --git a/bin/varnishtest/tests/v00058.vtc b/bin/varnishtest/tests/v00058.vtc index d76e3d397..bb6aa869a 100644 --- a/bin/varnishtest/tests/v00058.vtc +++ b/bin/varnishtest/tests/v00058.vtc @@ -117,7 +117,6 @@ server s1 { expect req.http.Bar == "bar" expect req.http.Baz == "baz" expect req.http.Quux == "quux" - expect req.http.Result == txresp } -start @@ -155,13 +154,13 @@ varnish v1 -vcl+backend { client c1 { txreq -url "/1" rxresp - expect resp.status == 500 - expect resp.reason == "Internal Server Error" + expect resp.status >= 500 + expect resp.status <= 503 } -run client c1 { txreq -url "/2" rxresp - expect resp.status == 503 - expect resp.reason == "VCL failed" + expect resp.status >= 500 + expect resp.status <= 503 } -run From phk at FreeBSD.org Mon Aug 13 08:53:06 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2018 08:53:06 +0000 (UTC) Subject: [master] 5d88d925b Make the client list all mgt CLI commands Message-ID: <20180813085306.D2396951AD@lists.varnish-cache.org> commit 5d88d925bcec72855f458ceb5ab3872c8b3f4998 Author: Poul-Henning Kamp Date: Mon Aug 13 08:51:41 2018 +0000 Make the client list all mgt CLI commands Fixes: #2682 diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c index 35dac06a6..b38387d67 100644 --- a/bin/varnishd/cache/cache_cli.c +++ b/bin/varnishd/cache/cache_cli.c @@ -100,7 +100,7 @@ CLI_Run(void) cli = VCLS_AddFd(cache_cls, heritage.cli_in, heritage.cli_out, NULL, NULL); AN(cli); - cli->auth = 1; // Non-zero to disable paranoia in vcli_serve + cli->auth = 255; // Non-zero to disable paranoia in vcli_serve do { i = VCLS_Poll(cache_cls, cli, -1); From phk at FreeBSD.org Mon Aug 13 09:16:07 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Mon, 13 Aug 2018 09:16:07 +0000 (UTC) Subject: [master] 948681c6b In curses mode, always filter in the counters necessary for the header lines. Message-ID: <20180813091608.18BF09595B@lists.varnish-cache.org> commit 948681c6b9acb350aed7766283d63d69c35ee393 Author: Poul-Henning Kamp Date: Mon Aug 13 09:14:52 2018 +0000 In curses mode, always filter in the counters necessary for the header lines. Fixes: #2678 diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c index 0a78a4513..74a8f5adf 100644 --- a/bin/varnishstat/varnishstat.c +++ b/bin/varnishstat/varnishstat.c @@ -264,6 +264,7 @@ main(int argc, char * const *argv) int once = 0, xml = 0, json = 0, f_list = 0, curses = 0; signed char opt; int i; + int has_f = 0; struct vsc *vsc; vut = VUT_InitProg(argc, argv, &vopt_spec); @@ -293,6 +294,7 @@ main(int argc, char * const *argv) break; case 'f': AN(VSC_Arg(vsc, opt, optarg)); + has_f = 1; break; case 'V': AN(VUT_Arg(vut, opt, optarg)); @@ -315,8 +317,15 @@ main(int argc, char * const *argv) if (VSM_Attach(vd, STDERR_FILENO)) VUT_Error(vut, 1, "%s", VSM_Error(vd)); - if (curses) + if (curses) { + if (has_f) { + AZ(VSC_Arg(vsc, 'f', "MGT.uptime")); + AZ(VSC_Arg(vsc, 'f', "MAIN.uptime")); + AZ(VSC_Arg(vsc, 'f', "MAIN.cache_hit")); + AZ(VSC_Arg(vsc, 'f', "MAIN.cache_miss")); + } do_curses(vd, vsc, 1.0); + } else if (xml) do_xml(vd, vsc); else if (json) From daghf at varnish-software.com Mon Aug 13 09:37:06 2018 From: daghf at varnish-software.com (Dag Haavi Finstad) Date: Mon, 13 Aug 2018 09:37:06 +0000 (UTC) Subject: [master] f3fc3c4b6 Fix a buffer overflow situation in h2_deliver Message-ID: <20180813093706.E922E9603D@lists.varnish-cache.org> commit f3fc3c4b6d6c895ba81471e2710373f74e7ee03c Author: Dag Haavi Finstad Date: Mon Aug 13 11:32:10 2018 +0200 Fix a buffer overflow situation in h2_deliver This still lacks error handling and thus is not a fix for #2589, but at least we're not writing past the end of the workspace any more. diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c index cb9c7d3f2..a36d657c0 100644 --- a/bin/varnishd/http2/cache_http2_deliver.c +++ b/bin/varnishd/http2/cache_http2_deliver.c @@ -160,34 +160,35 @@ h2_minimal_response(struct req *req, uint16_t status) return (0); } -static uint8_t * -h2_enc_len(uint8_t *p, unsigned bits, unsigned val) +static int +h2_enc_len(struct vsb *vsb, unsigned bits, unsigned val, uint8_t b0) { assert(bits < 8); unsigned mask = (1U << bits) - 1U; if (val >= mask) { - *p++ |= (uint8_t)mask; + AZ(VSB_putc(vsb, b0 | (uint8_t)mask)); val -= mask; while (val >= 128) { - *p++ = 0x80 | ((uint8_t)val & 0x7f); + AZ(VSB_putc(vsb, 0x80 | ((uint8_t)val & 0x7f))); val >>= 7; } } - *p++ = (uint8_t)val; - return (p); + AZ(VSB_putc(vsb, (uint8_t)val)); + return (0); } void v_matchproto_(vtr_deliver_f) h2_deliver(struct req *req, struct boc *boc, int sendbody) { ssize_t sz, sz1; - uint8_t *p; - unsigned u; + unsigned u, l; + uint8_t buf[6]; const char *r; struct http *hp; struct sess *sp; struct h2_req *r2; + struct vsb resp; int i, err; const struct hpack_static *hps; @@ -198,15 +199,14 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) sp = req->sp; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - (void)WS_Reserve(req->ws, 0); - p = (void*)req->ws->f; + l = WS_Reserve(req->ws, 0); + AN(VSB_new(&resp, req->ws->f, l, VSB_FIXEDLEN)); - p += h2_status(p, req->resp->status); + l = h2_status(buf, req->resp->status); + AZ(VSB_bcat(&resp, buf, l)); hp = req->resp; for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { - assert(WS_Inside(req->ws, p, NULL)); - r = strchr(hp->hd[u].b, ':'); AN(r); @@ -227,27 +227,24 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) VSLb(req->vsl, SLT_Debug, "HP {%d, \"%s\", \"%s\"} <%s>", hps->idx, hps->name, hps->val, hp->hd[u].b); - *p = 0x10; - p = h2_enc_len(p, 4, hps->idx); + AZ(h2_enc_len(&resp, 4, hps->idx, 0x10)); } else { - - *p++ = 0x10; + AZ(VSB_putc(&resp, 0x10)); sz--; - p = h2_enc_len(p, 7, sz); + AZ(h2_enc_len(&resp, 7, sz, 0)); for (sz1 = 0; sz1 < sz; sz1++) - *p++ = (uint8_t)tolower(hp->hd[u].b[sz1]); + AZ(VSB_putc(&resp, tolower(hp->hd[u].b[sz1]))); } while (vct_islws(*++r)) continue; sz = hp->hd[u].e - r; - p = h2_enc_len(p, 7, sz); - memcpy(p, r, sz); - p += sz; - assert(WS_Inside(req->ws, p, NULL)); + AZ(h2_enc_len(&resp, 7, sz, 0)); + AZ(VSB_bcat(&resp, r, sz)); } - sz = (char*)p - req->ws->f; + VSB_finish(&resp); + sz = VSB_len(&resp); AZ(req->wrk->v1l); From nils.goroll at uplex.de Mon Aug 13 13:51:12 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 13 Aug 2018 13:51:12 +0000 (UTC) Subject: [master] 46f1557dd properly declare vtc_h2_dectbl.h to automake and git Message-ID: <20180813135112.DCCE09CCD7@lists.varnish-cache.org> commit 46f1557dd80ffbd75fab924e48ecfd020437b1e0 Author: Nils Goroll Date: Mon Aug 13 15:35:30 2018 +0200 properly declare vtc_h2_dectbl.h to automake and git in order to have it build first and cleaned up fixes this issue when switching to an older branch: $ git checkout ... error: The following untracked working tree files would be overwritten by checkout: bin/varnishtest/vtc_h2_dectbl.h Please move or remove them before you switch branches. Aborting diff --git a/.gitignore b/.gitignore index cdba66f7f..113da821b 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ cscope.*out # Various auto-generated code snippets /bin/varnishd/vhp_hufdec.h /bin/varnishd/vhp_gen_hufdec +/bin/varnishtest/vtc_h2_dectbl.h /include/vcl.h /include/vrt_obj.h /include/vmod_abi.h diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index b34caa435..5c3cfae85 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -91,4 +91,8 @@ vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ mv $@_ $@ -CLEANFILES = $(builddir)/teken_state.h +BUILT_SOURCES = vtc_h2_dectbl.h + +CLEANFILES = \ + $(builddir)/teken_state.h \ + $(BUILT_SOURCES) From phk at FreeBSD.org Tue Aug 14 07:47:11 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 14 Aug 2018 07:47:11 +0000 (UTC) Subject: [master] 9d40f55a0 Make large integers work in VCL. Message-ID: <20180814074711.AC67F6F1D@lists.varnish-cache.org> commit 9d40f55a0eba59f9762a54f5f529b6b3fa7da038 Author: Poul-Henning Kamp Date: Tue Aug 14 07:45:23 2018 +0000 Make large integers work in VCL. Fixes: #2603 diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index da563157f..4bebb20ae 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -326,10 +326,16 @@ varnish v1 -vcl+backend { set resp.http.foo = (resp.http.foo + resp.http.bar) == ("X" + resp.http.foo); } + sub vcl_deliver { + set resp.http.p = (0 + 9223372036854775807); + set resp.http.n = (0 - 9223372036854775807); + } } -start client c1 { txreq rxresp expect resp.http.foo == "true" + expect resp.http.p == 9223372036854775807 + expect resp.http.n == -9223372036854775807 } -run diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index 6eba999d6..2b21aa0a2 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -80,6 +80,7 @@ tokens = { # These have handwritten recognizers "ID": None, "CNUM": None, + "FNUM": None, "CSTR": None, "EOI": None, "CSRC": None, diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index fef82ecef..3a6860abe 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -331,7 +331,6 @@ void Emit_UDS_Path(struct vcc *tl, const struct token *t_path, const char *errid); double vcc_TimeUnit(struct vcc *); void vcc_ByteVal(struct vcc *, double *); -void vcc_NumVal(struct vcc *, double *, int *); void vcc_Duration(struct vcc *tl, double *); unsigned vcc_UintVal(struct vcc *tl); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 39a01af38..b420dedf8 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -677,6 +677,7 @@ vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t, * '(' ExprCor ')' * symbol * CNUM + * FNUM * CSTR */ @@ -688,7 +689,6 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt) struct token *t; struct symbol *sym; double d; - int i; sign = ""; *e = NULL; @@ -782,34 +782,35 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt) *e = e1; return; case '-': - if (fmt != INT && fmt != REAL && fmt != DURATION) + if (fmt != INT && + fmt != REAL && + fmt != DURATION && + fmt != STRINGS) break; vcc_NextToken(tl); - ExpectErr(tl, CNUM); + if (tl->t->tok != FNUM && tl->t->tok != CNUM) + break; sign = "-"; /* FALLTHROUGH */ + case FNUM: case CNUM: - /* - * XXX: %g may not have enough decimals by default - * XXX: but %a is ugly, isn't it ? - */ assert(fmt != VOID); if (fmt == BYTES) { vcc_ByteVal(tl, &d); ERRCHK(tl); e1 = vcc_mk_expr(BYTES, "%.1f", d); } else { - vcc_NumVal(tl, &d, &i); - ERRCHK(tl); + t = tl->t; + vcc_NextToken(tl); if (tl->t->tok == ID) { - e1 = vcc_mk_expr(DURATION, "%s%g", - sign, d * vcc_TimeUnit(tl)); + e1 = vcc_mk_expr(DURATION, "(%s%.*s) * %g", + sign, PF(t), vcc_TimeUnit(tl)); ERRCHK(tl); - } else if (i || fmt == REAL) - e1 = vcc_mk_expr(REAL, "%s%f", sign, d); - else - e1 = vcc_mk_expr(INT, "%s%jd", - sign, (intmax_t)d); + } else if (fmt == REAL || t->tok == FNUM) { + e1 = vcc_mk_expr(REAL, "%s%.*s", sign, PF(t)); + } else { + e1 = vcc_mk_expr(INT, "%s%.*s", sign, PF(t)); + } } e1->constant = EXPR_CONST; *e = e1; diff --git a/lib/libvcc/vcc_parse.c b/lib/libvcc/vcc_parse.c index a81950a6c..a4bbf1182 100644 --- a/lib/libvcc/vcc_parse.c +++ b/lib/libvcc/vcc_parse.c @@ -275,31 +275,22 @@ vcc_ParseFunction(struct vcc *tl) static void vcc_ParseVcl(struct vcc *tl) { - struct token *tok0, *tok1, *tok2; + struct token *tok0; int syntax; assert(vcc_IdIs(tl->t, "vcl")); tok0 = tl->t; vcc_NextToken(tl); - tok1 = tl->t; - Expect(tl, CNUM); - syntax = (*tl->t->b - '0') * 10; - vcc_NextToken(tl); - Expect(tl, '.'); - vcc_NextToken(tl); - - Expect(tl, CNUM); - tok2 = tl->t; - syntax += (*tl->t->b - '0'); - vcc_NextToken(tl); - - if (tok1->e - tok1->b != 1 || tok2->e - tok2->b != 1) { + Expect(tl, FNUM); + if (tl->t->e - tl->t->b != 3 || tl->t->b[1] != '.') { VSB_printf(tl->sb, "Don't play silly buggers with VCL version numbers\n"); - vcc_ErrWhere2(tl, tok0, tl->t); + vcc_ErrWhere(tl, tl->t); ERRCHK(tl); } + syntax = (tl->t->b[0] - '0') * 10 + (tl->t->b[2] - '0'); + vcc_NextToken(tl); if (syntax < VCL_LOW || syntax > VCL_HIGH) { VSB_printf(tl->sb, "VCL version %.1f not supported.\n", diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c index 894397d1e..fcd37796c 100644 --- a/lib/libvcc/vcc_token.c +++ b/lib/libvcc/vcc_token.c @@ -505,7 +505,15 @@ vcc_Lexer(struct vcc *tl, struct source *sp) for (q = p; q < sp->e; q++) if (!vct_isdigit(*q)) break; - vcc_AddToken(tl, CNUM, p, q); + if (*q != '.') { + vcc_AddToken(tl, CNUM, p, q); + p = q; + continue; + } + for (++q; q < sp->e; q++) + if (!vct_isdigit(*q)) + break; + vcc_AddToken(tl, FNUM, p, q); p = q; continue; } diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 71db6a792..b28f1628f 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -348,50 +348,17 @@ vcc_UintVal(struct vcc *tl) return (d); } -/*-------------------------------------------------------------------- - * Recognize and convert { CNUM [ '.' [ CNUM ] ] } to double value - * The tokenizer made sure we only get digits and a '.' - */ - -void -vcc_NumVal(struct vcc *tl, double *d, int *frac) -{ - double e = 0.1; - const char *p; - - *frac = 0; - *d = 0.0; - Expect(tl, CNUM); - if (tl->err) { - *d = NAN; - return; - } - for (p = tl->t->b; p < tl->t->e; p++) { - *d *= 10; - *d += *p - '0'; - } - vcc_NextToken(tl); - if (tl->t->tok != '.') - return; - *frac = 1; - vcc_NextToken(tl); - if (tl->t->tok != CNUM) - return; - for (p = tl->t->b; p < tl->t->e; p++) { - *d += (*p - '0') * e; - e *= 0.1; - } - vcc_NextToken(tl); -} - static double vcc_DoubleVal(struct vcc *tl) { - double d; - int i; + const size_t l = tl->t->e - tl->t->b; + char buf[l + 1]; - vcc_NumVal(tl, &d, &i); - return (d); + assert(tl->t->tok == CNUM || tl->t->tok == FNUM); + memcpy(buf, tl->t->b, l); + vcc_NextToken(tl); + buf[l] = '\0'; + return (strtod(buf, NULL)); } /*--------------------------------------------------------------------*/ From phk at FreeBSD.org Wed Aug 15 12:39:08 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 15 Aug 2018 12:39:08 +0000 (UTC) Subject: [master] b51bc4a78 Warn about too many (>100) VCLs. Message-ID: <20180815123908.269A1AC4D3@lists.varnish-cache.org> commit b51bc4a787709d340d6753aa02025837183371c0 Author: Poul-Henning Kamp Date: Wed Aug 15 12:37:22 2018 +0000 Warn about too many (>100) VCLs. Two new paramters allow the limit and than handling (ignore, warn, fail) to be configured. Fixes #2713 diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c index 5974b589a..2b0e88cf1 100644 --- a/bin/varnishd/mgt/mgt_vcl.c +++ b/bin/varnishd/mgt/mgt_vcl.c @@ -52,6 +52,7 @@ static const char * const VCL_STATE_COLD = "cold"; static const char * const VCL_STATE_WARM = "warm"; static const char * const VCL_STATE_AUTO = "auto"; static const char * const VCL_STATE_LABEL = "label"; +static int vcl_count; struct vclprog; struct vmodfile; @@ -234,6 +235,8 @@ mgt_vcl_add(const char *name, const char *state) vp->warm = 1; VTAILQ_INSERT_TAIL(&vclhead, vp, list); + if (vp->state != VCL_STATE_LABEL) + vcl_count++; return (vp); } @@ -251,6 +254,8 @@ mgt_vcl_del(struct vclprog *vp) mgt_vcl_dep_del(VTAILQ_FIRST(&vp->dfrom)); VTAILQ_REMOVE(&vclhead, vp, list); + if (vp->state != VCL_STATE_LABEL) + vcl_count--; if (vp->fname != NULL) { AZ(unlink(vp->fname)); p = strrchr(vp->fname, '/'); @@ -465,6 +470,12 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, if (C_flag) { bprintf(buf, ".CflagTest.%d", (int)getpid()); vclname = buf; + } else if (vcl_count >= mgt_param.max_vcl && + mgt_param.max_vcl_handling == 2) { + VCLI_Out(cli, "Too many (%d) VCLs already loaded\n", vcl_count); + VCLI_Out(cli, "(See max_vcl and max_vcl_handling parameters)"); + VCLI_SetResult(cli, CLIS_CANT); + return; } if (state == NULL) @@ -494,6 +505,14 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc, if (active_vcl == NULL) active_vcl = vp; + if (cli->result == CLIS_OK && + vcl_count > mgt_param.max_vcl && + mgt_param.max_vcl_handling == 1) { + VCLI_Out(cli, "%d VCLs loaded\n", vcl_count); + VCLI_Out(cli, "Remember to vcl.discard the old/unused VCLs.\n"); + VCLI_Out(cli, "(See max_vcl and max_vcl_handling parameters)"); + } + if (!MCH_Running()) return; diff --git a/bin/varnishtest/tests/v00025.vtc b/bin/varnishtest/tests/v00025.vtc index 699137b0f..d3d0cf684 100644 --- a/bin/varnishtest/tests/v00025.vtc +++ b/bin/varnishtest/tests/v00025.vtc @@ -7,7 +7,23 @@ server s1 { txresp } -start -varnish v1 -syntax 4.0 -arg "-i J.F.Nobody" -vcl+backend { +# Test max_vcl param +varnish v1 -arg "-i J.F.Nobody" -vcl+backend { } -start + +varnish v1 -cliok "param.set max_vcl 2" +varnish v1 -cliok "param.set max_vcl_handling 2" + +varnish v1 -vcl+backend { } +varnish v1 -errvcl {Too many (2) VCLs already loaded} {} + +varnish v1 -cliok "param.set max_vcl_handling 1" + +varnish v1 -cliexpect "Remember to vcl.discard the old/unused VCLs." \ + {vcl.inline foobar "vcl 4.1; backend b1 {.host=\"${s1_addr}\";}"} + +varnish v1 -cliok "param.set max_vcl 100" + +varnish v1 -syntax 4.0 -vcl+backend { import std; import directors; @@ -78,7 +94,7 @@ varnish v1 -syntax 4.0 -arg "-i J.F.Nobody" -vcl+backend { set bereq.connect_timeout = 10s; } -} -start +} client c1 { txreq diff --git a/include/tbl/params.h b/include/tbl/params.h index 054b2f449..e583b3977 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -1519,6 +1519,38 @@ PARAM( /* func */ NULL ) +PARAM( + /* name */ max_vcl_handling, + /* typ */ uint, + /* min */ "0", + /* max */ "2", + /* default */ "1", + /* units */ NULL, + /* flags */ 0, + /* s-text */ + "Behaviour when attempting to exceed max_vcl loaded VCL.\n" + "\n* 0 - Ignore max_vcl parameter.\n" + "\n* 1 - Issue warning.\n" + "\n* 2 - Refuse loading VCLs.", + /* l-text */ "", + /* func */ NULL +) + +PARAM( + /* name */ max_vcl, + /* typ */ uint, + /* min */ "0", + /* max */ NULL, + /* default */ "100", + /* units */ NULL, + /* flags */ 0, + /* s-text */ + "Threshold of loaded VCL programs. (VCL labels are not counted.)" + " Parameter max_vcl_handling determines behaviour.", + /* l-text */ "", + /* func */ NULL +) + PARAM( /* name */ vsm_free_cooldown, /* typ */ timeout, From nils.goroll at uplex.de Thu Aug 16 08:52:21 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:21 +0000 (UTC) Subject: [6.0] d06e9af2c move the http_gzip_support check to the right place Message-ID: <20180816085221.9006B98557@lists.varnish-cache.org> commit d06e9af2cb2c49b52c6db43061395dfa1650d06d Author: Nils Goroll Date: Thu Mar 15 16:04:24 2018 +0100 move the http_gzip_support check to the right place Ref: #2610 Thank you to @fgsch for spotting Apologies to everyone for my insufficient understanding of the agreement about which fixes we push during the soak in period after release. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 36b1c50b9..9de528b3e 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -521,11 +521,6 @@ vbf_figure_out_vfp(struct busyobj *bo) * */ - if (! cache_param->http_gzip_support) { - bo->do_gzip = bo->do_gunzip = 0; - return (0); - } - if (http_GetStatus(bo->beresp) == 206) { if (bo->do_esi) { VSLb(bo->vsl, SLT_VCL_Error, @@ -536,6 +531,11 @@ vbf_figure_out_vfp(struct busyobj *bo) return (0); } + if (! cache_param->http_gzip_support) { + bo->do_gzip = bo->do_gunzip = 0; + return (0); + } + /* No body -> done */ if (bo->htc->body_status == BS_NONE || bo->htc->content_length == 0) { From nils.goroll at uplex.de Thu Aug 16 08:52:21 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:21 +0000 (UTC) Subject: [6.0] 5e2b0d8ab If gzip support is off, we still need to esi process Message-ID: <20180816085221.BE4709855A@lists.varnish-cache.org> commit 5e2b0d8abda18e807b73ed2f6c0746688001e85b Author: Nils Goroll Date: Thu Mar 15 16:30:38 2018 +0100 If gzip support is off, we still need to esi process Ref: #2610 with another thank you to @fgsch diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 9de528b3e..eb906b81b 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -531,10 +531,8 @@ vbf_figure_out_vfp(struct busyobj *bo) return (0); } - if (! cache_param->http_gzip_support) { + if (! cache_param->http_gzip_support) bo->do_gzip = bo->do_gunzip = 0; - return (0); - } /* No body -> done */ if (bo->htc->body_status == BS_NONE || From geoff at uplex.de Thu Aug 16 08:52:21 2018 From: geoff at uplex.de (Geoff Simmons) Date: Thu, 16 Aug 2018 08:52:21 +0000 (UTC) Subject: [6.0] 4db00afa9 Test error handling when the -a UDS path is too long. Message-ID: <20180816085221.EC8059855D@lists.varnish-cache.org> commit 4db00afa9face7fe55bf12f3b0f8cbcfd7282a09 Author: Geoff Simmons Date: Fri Mar 23 13:16:02 2018 +0100 Test error handling when the -a UDS path is too long. We currently suppress the error message that actually explains the problem. diff --git a/bin/varnishtest/tests/c00003.vtc b/bin/varnishtest/tests/c00003.vtc index 9dfb2200b..1c369bb07 100644 --- a/bin/varnishtest/tests/c00003.vtc +++ b/bin/varnishtest/tests/c00003.vtc @@ -18,6 +18,11 @@ shell -err -expect "Too many protocol sub-args" { varnishd -a 127.0.0.1:80000,HTTP,FOO -d } +# -a UDS path too long +shell -err -match "Got no socket" { + varnishd -a /Although/sizeof/sockaddr_un/sun_path/is/platform/specific/this/path/is/really/definitely/and/most/assuredly/too/long/on/any/platform/--/any/length/that/results/in/sizeof/sockaddr_un/being/greater/than/128/will/probably/be/enough/to/blow/it/up. -d +} + # -a relative path for a UDS address not permitted shell -err -expect "Unix domain socket addresses must be absolute paths" { varnishd -a foo/bar.sock -d From geoff at uplex.de Thu Aug 16 08:52:22 2018 From: geoff at uplex.de (Geoff Simmons) Date: Thu, 16 Aug 2018 08:52:22 +0000 (UTC) Subject: [6.0] ce91292da Always use bprintf() write to sockaddr_un.sun_path. Message-ID: <20180816085222.1EC0698563@lists.varnish-cache.org> commit ce91292da0a95cd874b97ba6af97564b99bb92f8 Author: Geoff Simmons Date: Fri Mar 23 13:42:21 2018 +0100 Always use bprintf() write to sockaddr_un.sun_path. We already check the -a user input and emit an error if the path is too long. bprintf() should help persuade static analysis tools that we won't overflow the fixed-size buffer. diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 796a11b3e..8ef0f3aa9 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -90,7 +90,7 @@ mac_opensocket(struct listen_sock *ls) ls->sock = VTCP_bind(ls->addr, NULL); else { uds.sun_family = PF_UNIX; - strcpy(uds.sun_path, ls->endpoint); + bprintf(uds.sun_path, "%s", ls->endpoint); ls->sock = VUS_bind(&uds, NULL); } fail = errno; diff --git a/lib/libvarnish/vus.c b/lib/libvarnish/vus.c index 69a223d94..6315d9533 100644 --- a/lib/libvarnish/vus.c +++ b/lib/libvarnish/vus.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "vdef.h" #include "vas.h" @@ -55,7 +56,7 @@ VUS_resolver(const char *path, vus_resolved_f *func, void *priv, *err = "Path too long for a Unix domain socket"; return(-1); } - strcpy(uds.sun_path, path); + bprintf(uds.sun_path, "%s", path); uds.sun_family = PF_UNIX; if (func != NULL) ret = func(priv, &uds); @@ -108,10 +109,8 @@ VUS_connect(const char *path, int msec) if (path == NULL) return (-1); - /* Attempt the connect */ - assert(strlen(path) + 1 <= sizeof(uds.sun_path)); uds.sun_family = PF_UNIX; - strcpy(uds.sun_path, path); + bprintf(uds.sun_path, "%s", path); AN(sl); s = socket(PF_UNIX, SOCK_STREAM, 0); From fgsch at lodoss.net Thu Aug 16 08:52:22 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:22 +0000 (UTC) Subject: [6.0] 9cf1ae9bd Exercise ESI with gzip support disabled Message-ID: <20180816085222.4311898568@lists.varnish-cache.org> commit 9cf1ae9bdecf2e95c986a360ecf0dec0de2a4d67 Author: Federico G. Schwindt Date: Fri Mar 23 11:39:31 2018 -0300 Exercise ESI with gzip support disabled Related to #2626. diff --git a/bin/varnishtest/tests/e00031.vtc b/bin/varnishtest/tests/e00031.vtc new file mode 100644 index 000000000..8089633b4 --- /dev/null +++ b/bin/varnishtest/tests/e00031.vtc @@ -0,0 +1,21 @@ +varnishtest "ESI with http_gzip_support off" + +server s1 { + rxreq + txresp -gzipbody {} + rxreq + txresp -gzipbody "bar" +} -start + +varnish v1 -arg "-p http_gzip_support=off" -vcl+backend { + sub vcl_backend_response { + set beresp.do_esi = true; + } +} -start + +client c1 { + txreq + rxresp + gunzip + expect resp.body == "bar" +} -run From nils.goroll at uplex.de Thu Aug 16 08:52:22 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:22 +0000 (UTC) Subject: [6.0] 221830d47 Add a histogram profile for ReqBody time Message-ID: <20180816085222.6536698571@lists.varnish-cache.org> commit 221830d47b51ccf826949f1d502809aeecff8863 Author: Nils Goroll Date: Wed Mar 21 10:39:48 2018 +0100 Add a histogram profile for ReqBody time diff --git a/bin/varnishhist/varnishhist_profiles.h b/bin/varnishhist/varnishhist_profiles.h index 68e109c90..a7295b670 100644 --- a/bin/varnishhist/varnishhist_profiles.h +++ b/bin/varnishhist/varnishhist_profiles.h @@ -41,6 +41,16 @@ HIS_PROF( " (first byte received) until ready to deliver the" " client response" ) +HIS_PROF( + "reqbodytime", // name + HIS_CLIENT, // HIS_CLIENT | HIS_BACKEND + SLT_Timestamp, // tag + "ReqBody:", // prefix + 3, // field + -6, // hist_low + 3, // hist_high + "graph the time for reading the request body" + ) HIS_PROF( "size", // name HIS_CLIENT, // HIS_CLIENT | HIS_BACKEND From nils.goroll at uplex.de Thu Aug 16 08:52:22 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:22 +0000 (UTC) Subject: [6.0] efb5d8018 avoid duplicate init Message-ID: <20180816085222.8684398575@lists.varnish-cache.org> commit efb5d801864f7746d656ff4b843cd3e5f0680348 Author: Nils Goroll Date: Wed Mar 21 14:22:34 2018 +0100 avoid duplicate init diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 3f725972b..dd7e49749 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -506,7 +506,6 @@ main(int argc, char **argv) pthread_t thr; int fnum = -1; struct profile cli_p = {0}; - cli_p.name = 0; vut = VUT_InitProg(argc, argv, &vopt_spec); AN(vut); From nils.goroll at uplex.de Thu Aug 16 08:52:22 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:22 +0000 (UTC) Subject: [6.0] 50926acbe varnishhish: Add a prefix to custom Profile definitions Message-ID: <20180816085222.ACFE498579@lists.varnish-cache.org> commit 50926acbe55b4f851e5f593dab5d17ca5dbd6e9b Author: Nils Goroll Date: Wed Mar 21 14:38:02 2018 +0100 varnishhish: Add a prefix to custom Profile definitions Without it, graphing Timestamp tags was impossible for all practical purposes diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index dd7e49749..27d3174bc 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -501,8 +501,8 @@ int main(int argc, char **argv) { int i; - const char *colon, *ptag; - const char *profile = "responsetime"; + char *colon; + const char *ptag, *profile = "responsetime"; pthread_t thr; int fnum = -1; struct profile cli_p = {0}; @@ -528,7 +528,7 @@ main(int argc, char **argv) profile = optarg; break; } - /* else it's a definition, we hope */ + /* else check if valid definition */ if (colon == optarg + 1 && (*optarg == 'b' || *optarg == 'c')) { cli_p.VSL_arg = *optarg; @@ -542,15 +542,27 @@ main(int argc, char **argv) } assert(colon); - if (sscanf(colon + 1, "%d:%d:%d", &cli_p.field, - &cli_p.hist_low, &cli_p.hist_high) != 3) - profile_error(optarg); match_tag = VSL_Name2Tag(ptag, colon - ptag); if (match_tag < 0) VUT_Error(vut, 1, "-P: '%s' is not a valid tag name", optarg); + + cli_p.prefix = colon + 1; + colon = strchr(colon + 1, ':'); + + if (colon == NULL) + profile_error(optarg); + + *colon = '\0'; + if (*cli_p.prefix == '\0') + cli_p.prefix = NULL; + + if (sscanf(colon + 1, "%d:%d:%d", &cli_p.field, + &cli_p.hist_low, &cli_p.hist_high) != 3) + profile_error(optarg); + if (VSL_tagflags[match_tag]) VUT_Error(vut, 1, "-P: '%s' is an unsafe or binary record", diff --git a/bin/varnishhist/varnishhist_options.h b/bin/varnishhist/varnishhist_options.h index 7ad374bf7..999a678f4 100644 --- a/bin/varnishhist/varnishhist_options.h +++ b/bin/varnishhist/varnishhist_options.h @@ -47,13 +47,14 @@ ) #define HIS_OPT_P \ - VOPT("P:", "[-P <[cb:]tag:field_num:min:max>]", \ + VOPT("P:", "[-P <[cb:]tag:[prefix]:field_num:min:max>]", \ "Custom profile definition", \ "Graph the given custom definition defined as: an optional" \ " (c)lient or (b)ackend filter (defaults to client), the" \ - " tag we'll look for, and the field number of the value we" \ - " are interested in. min and max are the boundaries of the" \ - " graph (these are power of ten)." \ + " tag we'll look for, a prefix to look for (can be empty," \ + " but must be terminated by a colon) and the field number" \ + " of the value we are interested in. min and max are the" \ + " boundaries of the graph (these are power of ten)." \ ) #define HIS_OPT_B \ diff --git a/doc/changes.rst b/doc/changes.rst index af44652d7..bb85dc2a4 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,3 +1,14 @@ +==================== +Varnish Cache master +==================== + +bundled tools +------------- + +* ``varnishhist``: The format of the ``-P`` argument has been changed + for custom profile definitions to also contain a prefix to match the + tag against. + ================================ Varnish Cache 6.0.0 (2018-03-15) ================================ From nils.goroll at uplex.de Thu Aug 16 08:52:22 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:22 +0000 (UTC) Subject: [6.0] 480da504f varnishhist -P: make graph boundary parameters optional Message-ID: <20180816085222.D158D9857F@lists.varnish-cache.org> commit 480da504f9fe623be1e38dd4da7ec34fb8421e67 Author: Nils Goroll Date: Wed Mar 21 15:00:02 2018 +0100 varnishhist -P: make graph boundary parameters optional diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 27d3174bc..b33f5ce73 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -549,9 +549,14 @@ main(int argc, char **argv) "-P: '%s' is not a valid tag name", optarg); + if (VSL_tagflags[match_tag]) + VUT_Error(vut, 1, + "-P: '%s' is an unsafe or binary record", + optarg); + cli_p.prefix = colon + 1; - colon = strchr(colon + 1, ':'); + colon = strchr(colon + 1, ':'); if (colon == NULL) profile_error(optarg); @@ -559,20 +564,24 @@ main(int argc, char **argv) if (*cli_p.prefix == '\0') cli_p.prefix = NULL; - if (sscanf(colon + 1, "%d:%d:%d", &cli_p.field, - &cli_p.hist_low, &cli_p.hist_high) != 3) + if (sscanf(colon + 1, "%d", &cli_p.field) != 1) profile_error(optarg); - if (VSL_tagflags[match_tag]) - VUT_Error(vut, 1, - "-P: '%s' is an unsafe or binary record", - optarg); - cli_p.name = "custom"; cli_p.tag = match_tag; + cli_p.hist_low = -6; + cli_p.hist_high = 3; profile = NULL; active_profile = &cli_p; + colon = strchr(colon + 1, ':'); + if (colon == NULL) + break; + + if (sscanf(colon + 1, "%d:%d", &cli_p.hist_low, + &cli_p.hist_high) != 2) + profile_error(optarg); + break; case 'B': timebend = strtod(optarg, NULL); diff --git a/bin/varnishhist/varnishhist_options.h b/bin/varnishhist/varnishhist_options.h index 999a678f4..0c04278fd 100644 --- a/bin/varnishhist/varnishhist_options.h +++ b/bin/varnishhist/varnishhist_options.h @@ -47,14 +47,15 @@ ) #define HIS_OPT_P \ - VOPT("P:", "[-P <[cb:]tag:[prefix]:field_num:min:max>]", \ + VOPT("P:", "[-P <[cb:]tag:[prefix]:field_num[:min:max]>]", \ "Custom profile definition", \ "Graph the given custom definition defined as: an optional" \ " (c)lient or (b)ackend filter (defaults to client), the" \ " tag we'll look for, a prefix to look for (can be empty," \ " but must be terminated by a colon) and the field number" \ " of the value we are interested in. min and max are the" \ - " boundaries of the graph (these are power of ten)." \ + " boundaries of the graph in power of ten and default to" \ + " -6 and 3." \ ) #define HIS_OPT_B \ From nils.goroll at uplex.de Thu Aug 16 08:52:23 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:23 +0000 (UTC) Subject: [6.0] c53197303 varnishhist test update Message-ID: <20180816085223.0E8979858A@lists.varnish-cache.org> commit c531973031fc747fd0bc670ecef2a0b14ae610d8 Author: Nils Goroll Date: Wed Mar 21 16:32:37 2018 +0100 varnishhist test update diff --git a/bin/varnishtest/tests/u00007.vtc b/bin/varnishtest/tests/u00007.vtc index 8a095d5f8..64e9dc7c5 100644 --- a/bin/varnishtest/tests/u00007.vtc +++ b/bin/varnishtest/tests/u00007.vtc @@ -23,7 +23,7 @@ shell -err -expect "Invalid grouping mode: raw" \ "varnishhist -g raw" shell -err -expect "-P: No such profile 'foo'" \ "varnishhist -P foo" -shell -err -expect "-P: 'foo:bar' is not a valid profile name or definition" \ - "varnishhist -P foo:bar" -shell -err -expect "-P: 'foo:0:0:0' is not a valid tag name" \ - "varnishhist -P foo:0:0:0" +shell -err -expect "-P: 'Timestamp:' is not a valid profile name or definition" \ + "varnishhist -P Timestamp::" +shell -err -expect "-P: 'foo::0:0:0' is not a valid tag name" \ + "varnishhist -P foo::0:0:0" From phk at FreeBSD.org Thu Aug 16 08:52:23 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:23 +0000 (UTC) Subject: [6.0] dd84d50be Introduce the macro 'testdir' which is an absolute path to the directory where the .vtc file lives. Message-ID: <20180816085223.4439B98598@lists.varnish-cache.org> commit dd84d50be041a766072d52987fd63062433dc8df Author: Poul-Henning Kamp Date: Mon Mar 26 12:30:29 2018 +0000 Introduce the macro 'testdir' which is an absolute path to the directory where the .vtc file lives. Suggested by: HAproxy diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 26a200226..62c83af14 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -189,6 +189,10 @@ macro_get(const char *b, const char *e) int l; char *retval = NULL; + AN(b); + if (e == NULL) + e = strchr(b, '\0'); + AN(e); l = e - b; if (l == 4 && !memcmp(b, "date", l)) { @@ -889,6 +893,8 @@ exec_file(const char *fn, const char *script, const char *tmpdir, char *logbuf, unsigned loglen) { FILE *f; + struct vsb *vsb; + const char *p; (void)signal(SIGPIPE, SIG_IGN); @@ -900,6 +906,21 @@ exec_file(const char *fn, const char *script, const char *tmpdir, init_macro(); init_server(); + vsb = VSB_new_auto(); + AN(vsb); + if (*fn != '/') + VSB_cat(vsb, macro_get("pwd", NULL)); + p = strrchr(fn, '/'); + if (p != NULL) { + VSB_putc(vsb, '/'); + VSB_bcat(vsb, fn, p - fn); + } + if (VSB_len == 0) + VSB_putc(vsb, '/'); + AZ(VSB_finish(vsb)); + macro_def(vltop, NULL, "testdir", "%s", VSB_data(vsb)); + VSB_destroy(&vsb); + /* Move into our tmpdir */ AZ(chdir(tmpdir)); macro_def(vltop, NULL, "tmpdir", "%s", tmpdir); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:23 +0000 (UTC) Subject: [6.0] 2a0725c09 Incomplete condition Message-ID: <20180816085223.79E65985A5@lists.varnish-cache.org> commit 2a0725c0930b09c120ef3912b7f96e41f162df0f Author: Dridi Boukelmoune Date: Mon Mar 26 22:30:04 2018 +0200 Incomplete condition diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 62c83af14..8d7f76438 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -915,7 +915,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir, VSB_putc(vsb, '/'); VSB_bcat(vsb, fn, p - fn); } - if (VSB_len == 0) + if (VSB_len(vsb) == 0) VSB_putc(vsb, '/'); AZ(VSB_finish(vsb)); macro_def(vltop, NULL, "testdir", "%s", VSB_data(vsb)); From phk at FreeBSD.org Thu Aug 16 08:52:23 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:23 +0000 (UTC) Subject: [6.0] 5823ee99c Extract the wait4() handling to a subroutine Message-ID: <20180816085223.AB202985B7@lists.varnish-cache.org> commit 5823ee99c3238e28bc1068e5fdc3ecdfffa29c86 Author: Poul-Henning Kamp Date: Tue Mar 27 08:05:12 2018 +0000 Extract the wait4() handling to a subroutine diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index b404552e0..8cb2640c4 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -138,6 +138,7 @@ void b64_settings(const struct http *hp, const char *s); struct vsb *vtc_hex_to_bin(struct vtclog *vl, const char *arg); void vtc_expect(struct vtclog *, const char *, const char *, const char *, const char *, const char *); +void vtc_wait4(struct vtclog *, long, int, int); /* vtc_term.c */ struct term *Term_New(struct vtclog *, int, int); diff --git a/bin/varnishtest/vtc_subr.c b/bin/varnishtest/vtc_subr.c index 2c1439a4c..4cdea40bc 100644 --- a/bin/varnishtest/vtc_subr.c +++ b/bin/varnishtest/vtc_subr.c @@ -29,9 +29,12 @@ #include "config.h" #include +#include #include #include #include +#include +#include #include "vct.h" #include "vnum.h" @@ -128,3 +131,37 @@ vtc_expect(struct vtclog *vl, vtc_log(vl, 4, "EXPECT %s (%s) %s \"%s\" match", olhs, lhs, cmp, rhs); } + +void +vtc_wait4(struct vtclog *vl, long pid, int expect_status, int expect_signal) +{ + int status, r; + struct rusage ru; + + r = wait4(pid, &status, 0, &ru); + if (r < 0) + vtc_fatal(vl, "wait4 failed on pid %ld: %s", + pid, strerror(errno)); + vtc_log(vl, 2, "WAIT4 pid=%ld r=%d status=0x%04x (user %.6f sys %.6f)", + pid, r, status, + ru.ru_utime.tv_sec + 1e-6 * ru.ru_utime.tv_usec, + ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec + ); + + if (WIFEXITED(status) && (WEXITSTATUS(status) == expect_status)) + return; + if (WIFSIGNALED(status) && (WTERMSIG(status) == expect_signal)) + return; +#ifdef WCOREDUMP + vtc_fatal(vl, "Bad exit code: 0x%04x exit 0x%x signal %d core %d", + status, + WEXITSTATUS(status), + WIFSIGNALED(status) ? WTERMSIG(status) : 0, + WCOREDUMP(status)); +#else + vtc_fatal(vl, "Bad exit code: 0x%04x exit 0x%x signal %d", + status, + WEXITSTATUS(status), + WIFSIGNALED(status) ? WTERMSIG(status) : 0); +#endif +} diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 12e424417..680c1aab7 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -29,9 +29,7 @@ #include "config.h" #include -#include #include -#include #include #include @@ -198,7 +196,7 @@ vsl_catchup(const struct varnish *v) int vsl_idle; vsl_idle = v->vsl_idle; - while (!vtc_error && v->pid && vsl_idle == v->vsl_idle) + while (!vtc_error && vsl_idle == v->vsl_idle) VTIM_sleep(0.1); } @@ -224,7 +222,7 @@ varnishlog_thread(void *priv) c = NULL; opt = 0; - while (v->pid || c != NULL) { + while (v->fds[1] > 0 || c != NULL) { if (c == NULL) { if (vtc_error) break; @@ -386,7 +384,7 @@ varnish_thread(void *priv) memset(fds, 0, sizeof fds); fds->fd = v->fds[0]; fds->events = POLLIN; - i = poll(fds, 1, 1000); + i = poll(fds, 1, 10000); if (i == 0) continue; if (fds->revents & POLLIN) { @@ -635,8 +633,6 @@ static void varnish_cleanup(struct varnish *v) { void *p; - int status, r; - struct rusage ru; /* Close the CLI connection */ closefd(&v->cli_fd); @@ -648,26 +644,11 @@ varnish_cleanup(struct varnish *v) AZ(pthread_join(v->tp, &p)); closefd(&v->fds[0]); - r = wait4(v->pid, &status, 0, &ru); - v->pid = 0; - vtc_log(v->vl, 2, "R %d Status: %04x (u %.6f s %.6f)", r, status, - ru.ru_utime.tv_sec + 1e-6 * ru.ru_utime.tv_usec, - ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec - ); - /* Pick up the VSL thread */ AZ(pthread_join(v->tp_vsl, &p)); - if (WIFEXITED(status) && (WEXITSTATUS(status) == v->expect_exit)) - return; -#ifdef WCOREDUMP - vtc_fatal(v->vl, "Bad exit code: %04x sig %x exit %x core %x", - status, WTERMSIG(status), WEXITSTATUS(status), - WCOREDUMP(status)); -#else - vtc_fatal(v->vl, "Bad exit code: %04x sig %x exit %x", - status, WTERMSIG(status), WEXITSTATUS(status)); -#endif + vtc_wait4(v->vl, v->pid, v->expect_exit, 0); + v->pid = 0; } /********************************************************************** From phk at FreeBSD.org Thu Aug 16 08:52:23 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:23 +0000 (UTC) Subject: [6.0] 1d5b03ebb Improve vtc_wait4() so it can also handle vtc_process' needs. Message-ID: <20180816085223.D52EF985C7@lists.varnish-cache.org> commit 1d5b03ebb856edc4bfedb71af0fa332d06fe8123 Author: Poul-Henning Kamp Date: Tue Mar 27 08:50:57 2018 +0000 Improve vtc_wait4() so it can also handle vtc_process' needs. diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 8cb2640c4..8f0d13094 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -138,7 +138,7 @@ void b64_settings(const struct http *hp, const char *s); struct vsb *vtc_hex_to_bin(struct vtclog *vl, const char *arg); void vtc_expect(struct vtclog *, const char *, const char *, const char *, const char *, const char *); -void vtc_wait4(struct vtclog *, long, int, int); +void vtc_wait4(struct vtclog *, long, int, int, int); /* vtc_term.c */ struct term *Term_New(struct vtclog *, int, int); diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index c2e9c9a60..7c371036b 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -32,8 +32,6 @@ #include "config.h" #include // Linux: struct winsize -#include -#include #include #include @@ -85,7 +83,6 @@ struct process { pthread_mutex_t mtx; pthread_t tp; unsigned hasthread; - int status; struct term *term; int lin; @@ -247,10 +244,9 @@ static void * process_thread(void *priv) { struct process *p; - struct rusage ru; struct vev_root *evb; struct vev *ev; - int core, sig, ext, r; + int r; CAST_OBJ_NOTNULL(p, priv, PROCESS_MAGIC); @@ -293,8 +289,8 @@ process_thread(void *priv) vtc_fatal(p->vl, "VEV_Once() = %d, error %s", r, strerror(errno)); - r = wait4(p->pid, &p->status, 0, &ru); - + vtc_wait4(p->vl, p->pid, + p->expect_exit, p->expect_signal, p->allow_core); closefd(&p->f_stdout); closefd(&p->f_stderr); @@ -304,35 +300,7 @@ process_thread(void *priv) macro_undef(p->vl, p->name, "pid"); p->pid = -1; - vtc_log(p->vl, 2, "R 0x%04x Status: %04x (u %.6f s %.6f)", - r, p->status, - ru.ru_utime.tv_sec + 1e-6 * ru.ru_utime.tv_usec, - ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec - ); - AZ(pthread_mutex_unlock(&p->mtx)); - sig = WTERMSIG(p->status); - ext = WEXITSTATUS(p->status); -#ifdef WCOREDUMP - core = WCOREDUMP(p->status); - vtc_log(p->vl, 2, "Exit code: %04x sig %d exit %d core %d", - p->status, sig, ext, core); -#else - core = 0; - vtc_log(p->vl, 2, "Exit code: %04x sig %d exit %d", - p->status, sig, ext); -#endif - if (core && !p->allow_core) - vtc_fatal(p->vl, "Core dump"); - if (p->expect_signal >= 0 && sig != p->expect_signal) - vtc_fatal(p->vl, "Expected signal %d got %d", - p->expect_signal, sig); - else if (sig != 0 && sig != -p->expect_signal) - vtc_fatal(p->vl, "Expected signal %d got %d", - -p->expect_signal, sig); - if (ext != p->expect_exit) - vtc_fatal(p->vl, "Expected exit %d got %d", - p->expect_exit, ext); VEV_Destroy(&evb); if (p->log == 1) { diff --git a/bin/varnishtest/vtc_subr.c b/bin/varnishtest/vtc_subr.c index 4cdea40bc..1a9ff1035 100644 --- a/bin/varnishtest/vtc_subr.c +++ b/bin/varnishtest/vtc_subr.c @@ -132,8 +132,22 @@ vtc_expect(struct vtclog *vl, olhs, lhs, cmp, rhs); } +/********************************************************************** + * Wait for a subprocess. + * + * if expect_signal > 0, the process must die on that signal. + * if expect_signal < 0, dying on that signal is allowed, but not required. + * if allow_core > 0, a coredump is allowed, but not required. + * otherwise, the process must die on exit(expect_status) + */ + +#ifndef WCOREDUMP +# define WCOREDUMP(s) (-1) +#endif + void -vtc_wait4(struct vtclog *vl, long pid, int expect_status, int expect_signal) +vtc_wait4(struct vtclog *vl, long pid, + int expect_status, int expect_signal, int allow_core) { int status, r; struct rusage ru; @@ -148,20 +162,21 @@ vtc_wait4(struct vtclog *vl, long pid, int expect_status, int expect_signal) ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec ); - if (WIFEXITED(status) && (WEXITSTATUS(status) == expect_status)) + if (WIFEXITED(status) && expect_signal <= 0 && + (WEXITSTATUS(status) == expect_status)) return; - if (WIFSIGNALED(status) && (WTERMSIG(status) == expect_signal)) + + if (expect_signal < 0) + expect_signal = -expect_signal; + + if (WIFSIGNALED(status) && WCOREDUMP(status) <= allow_core && + WTERMSIG(status) == expect_signal) return; -#ifdef WCOREDUMP - vtc_fatal(vl, "Bad exit code: 0x%04x exit 0x%x signal %d core %d", + vtc_log(vl, 1, "Expected exit: 0x%x signal: %d core: %d", + expect_status, expect_signal, allow_core); + vtc_fatal(vl, "Bad exit status: 0x%04x exit 0x%x signal %d core %d", status, WEXITSTATUS(status), WIFSIGNALED(status) ? WTERMSIG(status) : 0, WCOREDUMP(status)); -#else - vtc_fatal(vl, "Bad exit code: 0x%04x exit 0x%x signal %d", - status, - WEXITSTATUS(status), - WIFSIGNALED(status) ? WTERMSIG(status) : 0); -#endif } diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 680c1aab7..a1a5ed8c0 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -647,7 +647,7 @@ varnish_cleanup(struct varnish *v) /* Pick up the VSL thread */ AZ(pthread_join(v->tp_vsl, &p)); - vtc_wait4(v->vl, v->pid, v->expect_exit, 0); + vtc_wait4(v->vl, v->pid, v->expect_exit, 0, 0); v->pid = 0; } From phk at FreeBSD.org Thu Aug 16 08:52:24 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:24 +0000 (UTC) Subject: [6.0] a33b931e6 List commands in a single tbl-include file. Move misc commands to separate source file. Message-ID: <20180816085224.0E62B985EA@lists.varnish-cache.org> commit a33b931e6ddd9b6fa74782560b7334636a23749f Author: Poul-Henning Kamp Date: Tue Mar 27 09:11:23 2018 +0000 List commands in a single tbl-include file. Move misc commands to separate source file. diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 974aaf961..efbac2ab8 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -27,22 +27,24 @@ bin_PROGRAMS = varnishtest varnishtest_SOURCES = \ hpack.h \ programs.h \ + cmds.h \ vmods.h \ - vtc.c \ vtc.h \ + vtc.c \ vtc_barrier.c \ vtc_client.c \ - vtc_http.c \ - vtc_http.h \ - vtc_log.c \ - vtc_http2.c \ vtc_h2_dectbl.h \ vtc_h2_enctbl.h \ vtc_h2_hpack.c \ vtc_h2_priv.h \ vtc_h2_stattbl.h \ vtc_h2_tbl.c \ + vtc_http.c \ + vtc_http.h \ + vtc_http2.c \ + vtc_log.c \ vtc_logexp.c \ + vtc_misc.c \ vtc_main.c \ vtc_process.c \ vtc_proxy.c \ diff --git a/bin/varnishtest/cmds.h b/bin/varnishtest/cmds.h new file mode 100644 index 000000000..58c2e7b45 --- /dev/null +++ b/bin/varnishtest/cmds.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2018 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/*lint -save -e525 -e539 */ + +CMD(barrier) +CMD(client) +CMD(delay) +CMD(err_shell) +CMD(feature) +//CMD(haproxy) +CMD(logexpect) +CMD(process) +CMD(server) +CMD(setenv) +CMD(shell) +CMD(varnish) +CMD(varnishtest) +#undef CMD + +/*lint -restore */ diff --git a/bin/varnishtest/flint.lnt b/bin/varnishtest/flint.lnt index 1dc271674..25eace29a 100644 --- a/bin/varnishtest/flint.lnt +++ b/bin/varnishtest/flint.lnt @@ -35,6 +35,7 @@ -e788 // enum value not used in defaulted switch +-efile(451, cmds.h) -efile(451, vmods.h) -efile(451, programs.h) -efile(451, vtc_h2_stattbl.h) diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 8d7f76438..76f1e7a9c 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -31,10 +31,6 @@ #include #include -#include -#include -#include -#include #include #include #include @@ -44,8 +40,6 @@ #include "vtc.h" #include "vav.h" -#include "vnum.h" -#include "vre.h" #include "vtim.h" #ifdef HAVE_SYS_PERSONALITY_H @@ -57,8 +51,8 @@ volatile sig_atomic_t vtc_error; /* Error encountered */ int vtc_stop; /* Stops current test without error */ pthread_t vtc_thread; +int ign_unknown_macro = 0; static struct vtclog *vltop; -static int ign_unknown_macro = 0; /********************************************************************** * Macro facility @@ -426,436 +420,13 @@ reset_cmds(const struct cmds *cmd) cmd->cmd(NULL, NULL, NULL, NULL); } -/* SECTION: varnishtest varnishtest - * - * This should be the first command in your vtc as it will identify the test - * case with a short yet descriptive sentence. It takes exactly one argument, a - * string, eg:: - * - * varnishtest "Check that varnishtest is actually a valid command" - * - * It will also print that string in the log. - */ - -static void -cmd_varnishtest(CMD_ARGS) -{ - - (void)priv; - (void)cmd; - (void)vl; - - if (av == NULL) - return; - AZ(strcmp(av[0], "varnishtest")); - - vtc_log(vl, 1, "TEST %s", av[1]); - AZ(av[2]); -} - -/* SECTION: shell shell - * - * Pass the string given as argument to a shell. If you have multiple - * commands to run, you can use curly barces to describe a multi-lines - * script, eg:: - * - * shell { - * echo begin - * cat /etc/fstab - * echo end - * } - * - * By default a zero exit code is expected, otherwise the vtc will fail. - * - * Notice that the commandstring is prefixed with "exec 2>&1;" to join - * stderr and stdout back to the varnishtest process. - * - * Optional arguments: - * - * \-err - * Expect non-zero exit code. - * - * \-exit N - * Expect exit code N instead of zero. - * - * \-expect STRING - * Expect string to be found in stdout+err. - * - * \-match REGEXP - * Expect regexp to match the stdout+err output. - */ -/* SECTION: client-server.spec.shell shell - * - * Same as for the top-level shell. - */ - -static void -cmd_shell_engine(struct vtclog *vl, int ok, const char *cmd, - const char *expect, const char *re) -{ - struct vsb *vsb; - FILE *fp; - vre_t *vre = NULL; - const char *errptr; - int r, c; - int err; - - AN(vl); - AN(cmd); - vsb = VSB_new_auto(); - AN(vsb); - if (re != NULL) { - vre = VRE_compile(re, 0, &errptr, &err); - if (vre == NULL) - vtc_fatal(vl, "shell_match invalid regexp (\"%s\")", - re); - } - VSB_printf(vsb, "exec 2>&1 ; %s", cmd); - AZ(VSB_finish(vsb)); - vtc_dump(vl, 4, "shell_cmd", VSB_data(vsb), -1); - fp = popen(VSB_data(vsb), "r"); - if (fp == NULL) - vtc_fatal(vl, "popen fails: %s", strerror(errno)); - VSB_clear(vsb); - do { - c = getc(fp); - if (c != EOF) - VSB_putc(vsb, c); - } while (c != EOF); - r = pclose(fp); - AZ(VSB_finish(vsb)); - vtc_dump(vl, 4, "shell_out", VSB_data(vsb), VSB_len(vsb)); - vtc_log(vl, 4, "shell_status = 0x%04x", WEXITSTATUS(r)); - if (WIFSIGNALED(r)) - vtc_log(vl, 4, "shell_signal = %d", WTERMSIG(r)); - - if (ok < 0 && !WEXITSTATUS(r) && !WIFSIGNALED(r)) - vtc_fatal(vl, "shell did not fail as expected"); - else if (ok >= 0 && WEXITSTATUS(r) != ok) - vtc_fatal(vl, "shell_exit not as expected: " - "got 0x%04x wanted 0x%04x", WEXITSTATUS(r), ok); - - if (expect != NULL) { - if (strstr(VSB_data(vsb), expect) == NULL) - vtc_fatal(vl, - "shell_expect not found: (\"%s\")", expect); - else - vtc_log(vl, 4, "shell_expect found"); - } else if (vre != NULL) { - if (VRE_exec(vre, VSB_data(vsb), VSB_len(vsb), 0, 0, - NULL, 0, NULL) < 1) - vtc_fatal(vl, - "shell_match failed: (\"%s\")", re); - else - vtc_log(vl, 4, "shell_match succeeded"); - VRE_free(&vre); - } - VSB_destroy(&vsb); -} - - -void -cmd_shell(CMD_ARGS) -{ - const char *expect = NULL; - const char *re = NULL; - int n; - int ok = 0; - - (void)priv; - (void)cmd; - - if (av == NULL) - return; - for (n = 1; av[n] != NULL; n++) { - if (!strcmp(av[n], "-err")) { - ok = -1; - } else if (!strcmp(av[n], "-exit")) { - n += 1; - ok = atoi(av[n]); - } else if (!strcmp(av[n], "-expect")) { - if (re != NULL) - vtc_fatal(vl, - "Cannot use -expect with -match"); - n += 1; - expect = av[n]; - } else if (!strcmp(av[n], "-match")) { - if (expect != NULL) - vtc_fatal(vl, - "Cannot use -match with -expect"); - n += 1; - re = av[n]; - } else { - break; - } - } - AN(av[n]); - cmd_shell_engine(vl, ok, av[n], expect, re); -} - -/* SECTION: err_shell err_shell - * - * This is very similar to the the ``shell`` command, except it takes a first - * string as argument before the command:: - * - * err_shell "foo" "echo foo" - * - * err_shell expect the shell command to fail AND stdout to match the string, - * failing the test case otherwise. - */ - -static void -cmd_err_shell(CMD_ARGS) -{ - (void)priv; - (void)cmd; - - if (av == NULL) - return; - AN(av[1]); - AN(av[2]); - AZ(av[3]); - vtc_log(vl, 1, - "NOTICE: err_shell is deprecated, use 'shell -err -expect'"); - cmd_shell_engine(vl, -1, av[2], av[1], NULL); -} - -/* SECTION: setenv setenv - * - * Set or change an environment variable:: - * - * setenv FOO "bar baz" - * - * The above will set the environment variable $FOO to the value - * provided. There is also an ``-ifunset`` argument which will only - * set the value if the the environment variable does not already - * exist:: - * - * setenv -ifunset FOO quux - */ -static void -cmd_setenv(CMD_ARGS) -{ - int r; - int force; - - (void)priv; - (void)cmd; - - if (av == NULL) - return; - AN(av[1]); - AN(av[2]); - - force = 1; - if (strcmp("-ifunset", av[1]) == 0) { - force = 0; - av++; - AN(av[2]); - } - if (av[3] != NULL) - vtc_fatal(vl, "CMD setenv: Unexpected argument '%s'", av[3]); - r = setenv(av[1], av[2], force); - if (r != 0) - vtc_log(vl, 0, "CMD setenv %s=\"%s\" failed: %s", - av[1], av[2], strerror(errno)); -} - -/* SECTION: delay delay - * - * Sleep for the number of seconds specified in the argument. The number - * can include a fractional part, e.g. 1.5. - */ -/* SECTION: stream.spec.delay delay - * - * Same as for the top-level delay. - */ -void -cmd_delay(CMD_ARGS) -{ - double f; - - (void)priv; - (void)cmd; - if (av == NULL) - return; - AN(av[1]); - AZ(av[2]); - f = VNUM(av[1]); - if (isnan(f)) - vtc_fatal(vl, "Syntax error in number (%s)", av[1]); - vtc_log(vl, 3, "delaying %g second(s)", f); - VTIM_sleep(f); -} - -/* SECTION: feature feature - * - * Test that the required feature(s) for a test are available, and skip - * the test otherwise; or change the interpretation of the test, as - * documented below. feature takes any number of arguments from this list: - * - * SO_RCVTIMEO_WORKS - * The SO_RCVTIMEO socket option is working - * 64bit - * The environment is 64 bits - * !OSX - * The environment is not OSX - * dns - * DNS lookups are working - * topbuild - * varnishtest has been started with '-i' - * root - * varnishtest has been invoked by the root user - * user_varnish - * The varnish user is present - * user_vcache - * The vcache user is present - * group_varnish - * The varnish group is present - * cmd - * A command line that should execute with a zero exit status - * ignore_unknown_macro - * Do not fail the test if a string of the form ${...} is not - * recognized as a macro. - * term - * Support for ADM3A terminal - * - * persistent_storage - * Varnish was built with the deprecated persistent storage. - * - * Be careful with ignore_unknown_macro, because it may cause a test with a - * misspelled macro to fail silently. You should only need it if you must - * run a test with strings of the form "${...}". - */ - -#if WITH_PERSISTENT_STORAGE -static const unsigned with_persistent_storage = 1; -#else -static const unsigned with_persistent_storage = 0; -#endif - -static int -test_term(struct vtclog *vl) -{ - FILE *p; - int a, b; - - p = popen("tput -T ansi.sys clear 2>&1", "r"); - if (p == NULL) - return (0); - a = fgetc(p); - b = fgetc(p); - if (a == 0x1b && b == '[') - return (1); - vtc_log(vl, 3, "No 'ansi.sys' terminfo entry."); - return (0); -} - -static void -cmd_feature(CMD_ARGS) -{ - int r; - int good; - - (void)priv; - (void)cmd; - - if (av == NULL) - return; - -#define FEATURE(nm, tst) \ - do { \ - if (!strcmp(*av, nm)) { \ - if (tst) { \ - good = 1; \ - } else { \ - vtc_stop = 2; \ - } \ - } \ - } while (0) - - for (av++; *av != NULL; av++) { - good = 0; - if (!strcmp(*av, "SO_RCVTIMEO_WORKS")) { -#ifdef SO_RCVTIMEO_WORKS - good = 1; -#else - vtc_stop = 2; -#endif - } - - if (!strcmp(*av, "!OSX")) { -#if !defined(__APPLE__) || !defined(__MACH__) - good = 1; -#else - vtc_stop = 2; -#endif - } - FEATURE("pcre_jit", VRE_has_jit); - FEATURE("64bit", sizeof(void*) == 8); - FEATURE("dns", feature_dns); - FEATURE("topbuild", iflg); - FEATURE("root", !geteuid()); - FEATURE("user_varnish", getpwnam("varnish") != NULL); - FEATURE("user_vcache", getpwnam("vcache") != NULL); - FEATURE("group_varnish", getgrnam("varnish") != NULL); - FEATURE("term", test_term(vl)); - FEATURE("persistent_storage", with_persistent_storage); - - if (!strcmp(*av, "disable_aslr")) { - good = 1; -#ifdef HAVE_SYS_PERSONALITY_H - r = personality(0xffffffff); - r = personality(r | ADDR_NO_RANDOMIZE); - if (r < 0) { - good = 0; - vtc_stop = 2; - } -#endif - } else if (!strcmp(*av, "cmd")) { - av++; - if (*av == NULL) - vtc_fatal(vl, "Missing the command-line"); - r = system(*av); - if (WEXITSTATUS(r) == 0) - good = 1; - else - vtc_stop = 2; - } else if (!strcmp(*av, "ignore_unknown_macro")) { - ign_unknown_macro = 1; - good = 1; - } - if (good) - continue; - - if (!vtc_stop) - vtc_fatal(vl, "FAIL test, unknown feature: %s", *av); - else - vtc_log(vl, 1, - "SKIPPING test, lacking feature: %s", *av); - return; - } -} - /********************************************************************** * Execute a file */ static const struct cmds cmds[] = { #define CMD(n) { #n, cmd_##n }, - CMD(server) - CMD(client) - CMD(varnish) - CMD(delay) - CMD(varnishtest) - CMD(shell) - CMD(err_shell) - CMD(barrier) - CMD(feature) - CMD(logexpect) - CMD(process) - CMD(setenv) -#undef CMD +#include "cmds.h" { NULL, NULL } }; diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 8f0d13094..387181c08 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -69,16 +69,8 @@ void parse_string(const char *spec, const struct cmds *cmd, void *priv, struct vtclog *vl); int fail_out(void); -#define CMD(n) cmd_f cmd_##n -CMD(delay); -CMD(server); -CMD(client); -CMD(varnish); -CMD(barrier); -CMD(logexpect); -CMD(process); -CMD(shell); -#undef CMD +#define CMD(n) cmd_f cmd_##n; +#include "cmds.h" extern volatile sig_atomic_t vtc_error; /* Error, bail out */ extern int vtc_stop; /* Abandon current test, no error */ @@ -90,6 +82,7 @@ extern struct vsb *params_vsb; extern int leave_temp; extern int vtc_witness; extern int feature_dns; +extern int ign_unknown_macro; void init_server(void); diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c new file mode 100644 index 000000000..30f404ed3 --- /dev/null +++ b/bin/varnishtest/vtc_misc.c @@ -0,0 +1,458 @@ +/*- + * Copyright (c) 2008-2011 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vtc.h" + +#include "vnum.h" +#include "vre.h" +#include "vtim.h" + +/* SECTION: varnishtest varnishtest + * + * This should be the first command in your vtc as it will identify the test + * case with a short yet descriptive sentence. It takes exactly one argument, a + * string, eg:: + * + * varnishtest "Check that varnishtest is actually a valid command" + * + * It will also print that string in the log. + */ + +void v_matchproto_(cmd_f) +cmd_varnishtest(CMD_ARGS) +{ + + (void)priv; + (void)cmd; + (void)vl; + + if (av == NULL) + return; + AZ(strcmp(av[0], "varnishtest")); + + vtc_log(vl, 1, "TEST %s", av[1]); + AZ(av[2]); +} + +/* SECTION: shell shell + * + * Pass the string given as argument to a shell. If you have multiple + * commands to run, you can use curly barces to describe a multi-lines + * script, eg:: + * + * shell { + * echo begin + * cat /etc/fstab + * echo end + * } + * + * By default a zero exit code is expected, otherwise the vtc will fail. + * + * Notice that the commandstring is prefixed with "exec 2>&1;" to join + * stderr and stdout back to the varnishtest process. + * + * Optional arguments: + * + * \-err + * Expect non-zero exit code. + * + * \-exit N + * Expect exit code N instead of zero. + * + * \-expect STRING + * Expect string to be found in stdout+err. + * + * \-match REGEXP + * Expect regexp to match the stdout+err output. + */ +/* SECTION: client-server.spec.shell shell + * + * Same as for the top-level shell. + */ + +static void +cmd_shell_engine(struct vtclog *vl, int ok, const char *cmd, + const char *expect, const char *re) +{ + struct vsb *vsb; + FILE *fp; + vre_t *vre = NULL; + const char *errptr; + int r, c; + int err; + + AN(vl); + AN(cmd); + vsb = VSB_new_auto(); + AN(vsb); + if (re != NULL) { + vre = VRE_compile(re, 0, &errptr, &err); + if (vre == NULL) + vtc_fatal(vl, "shell_match invalid regexp (\"%s\")", + re); + } + VSB_printf(vsb, "exec 2>&1 ; %s", cmd); + AZ(VSB_finish(vsb)); + vtc_dump(vl, 4, "shell_cmd", VSB_data(vsb), -1); + fp = popen(VSB_data(vsb), "r"); + if (fp == NULL) + vtc_fatal(vl, "popen fails: %s", strerror(errno)); + VSB_clear(vsb); + do { + c = getc(fp); + if (c != EOF) + VSB_putc(vsb, c); + } while (c != EOF); + r = pclose(fp); + AZ(VSB_finish(vsb)); + vtc_dump(vl, 4, "shell_out", VSB_data(vsb), VSB_len(vsb)); + vtc_log(vl, 4, "shell_status = 0x%04x", WEXITSTATUS(r)); + if (WIFSIGNALED(r)) + vtc_log(vl, 4, "shell_signal = %d", WTERMSIG(r)); + + if (ok < 0 && !WEXITSTATUS(r) && !WIFSIGNALED(r)) + vtc_fatal(vl, "shell did not fail as expected"); + else if (ok >= 0 && WEXITSTATUS(r) != ok) + vtc_fatal(vl, "shell_exit not as expected: " + "got 0x%04x wanted 0x%04x", WEXITSTATUS(r), ok); + + if (expect != NULL) { + if (strstr(VSB_data(vsb), expect) == NULL) + vtc_fatal(vl, + "shell_expect not found: (\"%s\")", expect); + else + vtc_log(vl, 4, "shell_expect found"); + } else if (vre != NULL) { + if (VRE_exec(vre, VSB_data(vsb), VSB_len(vsb), 0, 0, + NULL, 0, NULL) < 1) + vtc_fatal(vl, + "shell_match failed: (\"%s\")", re); + else + vtc_log(vl, 4, "shell_match succeeded"); + VRE_free(&vre); + } + VSB_destroy(&vsb); +} + + +void +cmd_shell(CMD_ARGS) +{ + const char *expect = NULL; + const char *re = NULL; + int n; + int ok = 0; + + (void)priv; + (void)cmd; + + if (av == NULL) + return; + for (n = 1; av[n] != NULL; n++) { + if (!strcmp(av[n], "-err")) { + ok = -1; + } else if (!strcmp(av[n], "-exit")) { + n += 1; + ok = atoi(av[n]); + } else if (!strcmp(av[n], "-expect")) { + if (re != NULL) + vtc_fatal(vl, + "Cannot use -expect with -match"); + n += 1; + expect = av[n]; + } else if (!strcmp(av[n], "-match")) { + if (expect != NULL) + vtc_fatal(vl, + "Cannot use -match with -expect"); + n += 1; + re = av[n]; + } else { + break; + } + } + AN(av[n]); + cmd_shell_engine(vl, ok, av[n], expect, re); +} + +/* SECTION: err_shell err_shell + * + * This is very similar to the the ``shell`` command, except it takes a first + * string as argument before the command:: + * + * err_shell "foo" "echo foo" + * + * err_shell expect the shell command to fail AND stdout to match the string, + * failing the test case otherwise. + */ + +void v_matchproto_(cmd_f) +cmd_err_shell(CMD_ARGS) +{ + (void)priv; + (void)cmd; + + if (av == NULL) + return; + AN(av[1]); + AN(av[2]); + AZ(av[3]); + vtc_log(vl, 1, + "NOTICE: err_shell is deprecated, use 'shell -err -expect'"); + cmd_shell_engine(vl, -1, av[2], av[1], NULL); +} + +/* SECTION: setenv setenv + * + * Set or change an environment variable:: + * + * setenv FOO "bar baz" + * + * The above will set the environment variable $FOO to the value + * provided. There is also an ``-ifunset`` argument which will only + * set the value if the the environment variable does not already + * exist:: + * + * setenv -ifunset FOO quux + */ + +void v_matchproto_(cmd_f) +cmd_setenv(CMD_ARGS) +{ + int r; + int force; + + (void)priv; + (void)cmd; + + if (av == NULL) + return; + AN(av[1]); + AN(av[2]); + + force = 1; + if (strcmp("-ifunset", av[1]) == 0) { + force = 0; + av++; + AN(av[2]); + } + if (av[3] != NULL) + vtc_fatal(vl, "CMD setenv: Unexpected argument '%s'", av[3]); + r = setenv(av[1], av[2], force); + if (r != 0) + vtc_log(vl, 0, "CMD setenv %s=\"%s\" failed: %s", + av[1], av[2], strerror(errno)); +} + +/* SECTION: delay delay + * + * Sleep for the number of seconds specified in the argument. The number + * can include a fractional part, e.g. 1.5. + */ +/* SECTION: stream.spec.delay delay + * + * Same as for the top-level delay. + */ +void +cmd_delay(CMD_ARGS) +{ + double f; + + (void)priv; + (void)cmd; + if (av == NULL) + return; + AN(av[1]); + AZ(av[2]); + f = VNUM(av[1]); + if (isnan(f)) + vtc_fatal(vl, "Syntax error in number (%s)", av[1]); + vtc_log(vl, 3, "delaying %g second(s)", f); + VTIM_sleep(f); +} + +/* SECTION: feature feature + * + * Test that the required feature(s) for a test are available, and skip + * the test otherwise; or change the interpretation of the test, as + * documented below. feature takes any number of arguments from this list: + * + * SO_RCVTIMEO_WORKS + * The SO_RCVTIMEO socket option is working + * 64bit + * The environment is 64 bits + * !OSX + * The environment is not OSX + * dns + * DNS lookups are working + * topbuild + * varnishtest has been started with '-i' + * root + * varnishtest has been invoked by the root user + * user_varnish + * The varnish user is present + * user_vcache + * The vcache user is present + * group_varnish + * The varnish group is present + * cmd + * A command line that should execute with a zero exit status + * ignore_unknown_macro + * Do not fail the test if a string of the form ${...} is not + * recognized as a macro. + * term + * Support for ADM3A terminal + * + * persistent_storage + * Varnish was built with the deprecated persistent storage. + * + * Be careful with ignore_unknown_macro, because it may cause a test with a + * misspelled macro to fail silently. You should only need it if you must + * run a test with strings of the form "${...}". + */ + +#if WITH_PERSISTENT_STORAGE +static const unsigned with_persistent_storage = 1; +#else +static const unsigned with_persistent_storage = 0; +#endif + +static int +test_term(struct vtclog *vl) +{ + FILE *p; + int a, b; + + p = popen("tput -T ansi.sys clear 2>&1", "r"); + if (p == NULL) + return (0); + a = fgetc(p); + b = fgetc(p); + if (a == 0x1b && b == '[') + return (1); + vtc_log(vl, 3, "No 'ansi.sys' terminfo entry."); + return (0); +} + +void v_matchproto_(cmd_f) +cmd_feature(CMD_ARGS) +{ + int r; + int good; + + (void)priv; + (void)cmd; + + if (av == NULL) + return; + +#define FEATURE(nm, tst) \ + do { \ + if (!strcmp(*av, nm)) { \ + if (tst) { \ + good = 1; \ + } else { \ + vtc_stop = 2; \ + } \ + } \ + } while (0) + + for (av++; *av != NULL; av++) { + good = 0; + if (!strcmp(*av, "SO_RCVTIMEO_WORKS")) { +#ifdef SO_RCVTIMEO_WORKS + good = 1; +#else + vtc_stop = 2; +#endif + } + + if (!strcmp(*av, "!OSX")) { +#if !defined(__APPLE__) || !defined(__MACH__) + good = 1; +#else + vtc_stop = 2; +#endif + } + FEATURE("pcre_jit", VRE_has_jit); + FEATURE("64bit", sizeof(void*) == 8); + FEATURE("dns", feature_dns); + FEATURE("topbuild", iflg); + FEATURE("root", !geteuid()); + FEATURE("user_varnish", getpwnam("varnish") != NULL); + FEATURE("user_vcache", getpwnam("vcache") != NULL); + FEATURE("group_varnish", getgrnam("varnish") != NULL); + FEATURE("term", test_term(vl)); + FEATURE("persistent_storage", with_persistent_storage); + + if (!strcmp(*av, "disable_aslr")) { + good = 1; +#ifdef HAVE_SYS_PERSONALITY_H + r = personality(0xffffffff); + r = personality(r | ADDR_NO_RANDOMIZE); + if (r < 0) { + good = 0; + vtc_stop = 2; + } +#endif + } else if (!strcmp(*av, "cmd")) { + av++; + if (*av == NULL) + vtc_fatal(vl, "Missing the command-line"); + r = system(*av); + if (WEXITSTATUS(r) == 0) + good = 1; + else + vtc_stop = 2; + } else if (!strcmp(*av, "ignore_unknown_macro")) { + ign_unknown_macro = 1; + good = 1; + } + if (good) + continue; + + if (!vtc_stop) + vtc_fatal(vl, "FAIL test, unknown feature: %s", *av); + else + vtc_log(vl, 1, + "SKIPPING test, lacking feature: %s", *av); + return; + } +} From nils.goroll at uplex.de Thu Aug 16 08:52:24 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:24 +0000 (UTC) Subject: [6.0] 943bbfa21 grammar micro-fix Message-ID: <20180816085224.31ACE98602@lists.varnish-cache.org> commit 943bbfa21d63f5913023cd6fed87cd7412054ad2 Author: Nils Goroll Date: Tue Mar 27 11:12:26 2018 +0200 grammar micro-fix diff --git a/bin/varnishhist/varnishhist_options.h b/bin/varnishhist/varnishhist_options.h index 0c04278fd..1bf1de7c7 100644 --- a/bin/varnishhist/varnishhist_options.h +++ b/bin/varnishhist/varnishhist_options.h @@ -54,7 +54,7 @@ " tag we'll look for, a prefix to look for (can be empty," \ " but must be terminated by a colon) and the field number" \ " of the value we are interested in. min and max are the" \ - " boundaries of the graph in power of ten and default to" \ + " boundaries of the graph in powers of ten and default to" \ " -6 and 3." \ ) From phk at FreeBSD.org Thu Aug 16 08:52:24 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:24 +0000 (UTC) Subject: [6.0] 3db978554 Also move personality.h #include Message-ID: <20180816085224.5749698627@lists.varnish-cache.org> commit 3db978554a69b5aea1a2baca0be7de1d7288df77 Author: Poul-Henning Kamp Date: Tue Mar 27 09:15:06 2018 +0000 Also move personality.h #include diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 76f1e7a9c..53d32328c 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -42,10 +42,6 @@ #include "vav.h" #include "vtim.h" -#ifdef HAVE_SYS_PERSONALITY_H -# include -#endif - #define MAX_TOKENS 200 volatile sig_atomic_t vtc_error; /* Error encountered */ diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c index 30f404ed3..55294e8cf 100644 --- a/bin/varnishtest/vtc_misc.c +++ b/bin/varnishtest/vtc_misc.c @@ -39,6 +39,10 @@ #include #include +#ifdef HAVE_SYS_PERSONALITY_H +# include +#endif + #include "vtc.h" #include "vnum.h" From phk at FreeBSD.org Thu Aug 16 08:52:24 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:24 +0000 (UTC) Subject: [6.0] 0f53c785d Expose VPF_Read() Message-ID: <20180816085224.7EE0898637@lists.varnish-cache.org> commit 0f53c785d4e815cc2800eec24a7fd008f47ef35f Author: Poul-Henning Kamp Date: Tue Mar 27 11:11:34 2018 +0000 Expose VPF_Read() diff --git a/include/vpf.h b/include/vpf.h index 822f2d360..d5266ac7c 100644 --- a/include/vpf.h +++ b/include/vpf.h @@ -36,5 +36,6 @@ struct vpf_fh *VPF_Open(const char *path, mode_t mode, pid_t *pidptr); int VPF_Write(struct vpf_fh *pfh); int VPF_Close(struct vpf_fh *pfh); int VPF_Remove(struct vpf_fh *pfh); +int VPF_read(const char *path, pid_t *); #endif diff --git a/lib/libvarnish/vpf.c b/lib/libvarnish/vpf.c index 5626b9e84..915a028ec 100644 --- a/lib/libvarnish/vpf.c +++ b/lib/libvarnish/vpf.c @@ -72,8 +72,8 @@ vpf_verify(const struct vpf_fh *pfh) return (0); } -static int -vpf_read(const char *path, pid_t *pidptr) +int +VPF_read(const char *path, pid_t *pidptr) { char buf[16], *endptr; int error, fd, i; @@ -129,7 +129,7 @@ VPF_Open(const char *path, mode_t mode, pid_t *pidptr) O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NONBLOCK, mode); if (fd == -1) { if (errno == EWOULDBLOCK && pidptr != NULL) { - errno = vpf_read(pfh->pf_path, pidptr); + errno = VPF_read(pfh->pf_path, pidptr); if (errno == 0) errno = EEXIST; } From phk at FreeBSD.org Thu Aug 16 08:52:24 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:24 +0000 (UTC) Subject: [6.0] c4d8fadc5 Make listening to stdout/err a convenience function Message-ID: <20180816085224.A8E1498642@lists.varnish-cache.org> commit c4d8fadc5490306576e0d5ed2284cca9cd2d3177 Author: Poul-Henning Kamp Date: Tue Mar 27 11:20:19 2018 +0000 Make listening to stdout/err a convenience function diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 387181c08..8878e1d37 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -132,6 +132,7 @@ struct vsb *vtc_hex_to_bin(struct vtclog *vl, const char *arg); void vtc_expect(struct vtclog *, const char *, const char *, const char *, const char *, const char *); void vtc_wait4(struct vtclog *, long, int, int, int); +void *vtc_record(struct vtclog *, int); /* vtc_term.c */ struct term *Term_New(struct vtclog *, int, int); diff --git a/bin/varnishtest/vtc_subr.c b/bin/varnishtest/vtc_subr.c index 1a9ff1035..39cafbefe 100644 --- a/bin/varnishtest/vtc_subr.c +++ b/bin/varnishtest/vtc_subr.c @@ -31,15 +31,19 @@ #include #include #include +#include #include #include +#include #include #include +#include "vtc.h" + #include "vct.h" #include "vnum.h" #include "vre.h" -#include "vtc.h" +#include "vtcp.h" struct vsb * vtc_hex_to_bin(struct vtclog *vl, const char *arg) @@ -180,3 +184,34 @@ vtc_wait4(struct vtclog *vl, long pid, WIFSIGNALED(status) ? WTERMSIG(status) : 0, WCOREDUMP(status)); } + +void * +vtc_record(struct vtclog *vl, int fd) +{ + char buf[65536]; + struct pollfd fds[1]; + int i; + + (void)VTCP_nonblocking(fd); + while (1) { + memset(fds, 0, sizeof fds); + fds->fd = fd; + fds->events = POLLIN; + i = poll(fds, 1, 10000); + if (i == 0) + continue; + if (fds->revents & POLLIN) { + i = read(fd, buf, sizeof buf - 1); + if (i > 0) { + buf[i] = '\0'; + vtc_dump(vl, 3, "debug", buf, -2); + } + } + if (fds->revents & (POLLERR|POLLHUP)) { + vtc_log(vl, 4, "STDOUT poll 0x%x", fds->revents); + break; + } + } + return (NULL); +} + diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index a1a5ed8c0..d09d7cf45 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -374,32 +374,9 @@ static void * varnish_thread(void *priv) { struct varnish *v; - char buf[65536]; - struct pollfd fds[1]; - int i; CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC); - (void)VTCP_nonblocking(v->fds[0]); - while (1) { - memset(fds, 0, sizeof fds); - fds->fd = v->fds[0]; - fds->events = POLLIN; - i = poll(fds, 1, 10000); - if (i == 0) - continue; - if (fds->revents & POLLIN) { - i = read(v->fds[0], buf, sizeof buf - 1); - if (i > 0) { - buf[i] = '\0'; - vtc_dump(v->vl, 3, "debug", buf, -2); - } - } - if (fds->revents & (POLLERR|POLLHUP)) { - vtc_log(v->vl, 4, "STDOUT poll 0x%x", fds->revents); - break; - } - } - return (NULL); + return (vtc_record(v->vl, v->fds[0])); } /********************************************************************** From fgsch at lodoss.net Thu Aug 16 08:52:24 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:24 +0000 (UTC) Subject: [6.0] 77663a93f Polish Message-ID: <20180816085224.D210C9864C@lists.varnish-cache.org> commit 77663a93f2c351fa86476bed45bcae52fe5f8f49 Author: Federico G. Schwindt Date: Mon Mar 26 13:46:23 2018 -0300 Polish diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index eb906b81b..27e7e70c9 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -531,9 +531,6 @@ vbf_figure_out_vfp(struct busyobj *bo) return (0); } - if (! cache_param->http_gzip_support) - bo->do_gzip = bo->do_gunzip = 0; - /* No body -> done */ if (bo->htc->body_status == BS_NONE || bo->htc->content_length == 0) { @@ -543,6 +540,9 @@ vbf_figure_out_vfp(struct busyobj *bo) return (0); } + if (!cache_param->http_gzip_support) + bo->do_gzip = bo->do_gunzip = 0; + bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"); bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL); assert(bo->is_gzip == 0 || bo->is_gunzip == 0); From fgsch at lodoss.net Thu Aug 16 08:52:25 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] 5005595f2 Whitespace and related OCD Message-ID: <20180816085225.0727298656@lists.varnish-cache.org> commit 5005595f263dcbc129b70e2445a393195cc9cc02 Author: Federico G. Schwindt Date: Tue Mar 27 01:06:49 2018 -0300 Whitespace and related OCD diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 74b29d6d2..392baba1d 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -443,11 +443,11 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC); if (vrt->path == NULL) - assert(vrt->ipv4_suckaddr != NULL - || vrt->ipv6_suckaddr != NULL); + assert(vrt->ipv4_suckaddr != NULL || + vrt->ipv6_suckaddr != NULL); else - assert(vrt->ipv4_suckaddr == NULL - && vrt->ipv6_suckaddr == NULL); + assert(vrt->ipv4_suckaddr == NULL && + vrt->ipv6_suckaddr == NULL); vcl = ctx->vcl; AN(vcl); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 1db47c480..4c8fad090 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -186,9 +186,9 @@ cnt_deliver(struct worker *wrk, struct req *req) assert(wrk->handling == VCL_RET_DELIVER); - if (req->esi_level == 0 - && http_IsStatus(req->resp, 200) - && req->http->conds && RFC2616_Do_Cond(req)) + if (req->esi_level == 0 && + http_IsStatus(req->resp, 200) && + req->http->conds && RFC2616_Do_Cond(req)) http_PutResponse(req->resp, "HTTP/1.1", 304, NULL); req->req_step = R_STP_TRANSMIT; diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c index e9fa812f9..86777ae6c 100644 --- a/bin/varnishd/cache/cache_tcp_pool.c +++ b/bin/varnishd/cache/cache_tcp_pool.c @@ -656,8 +656,8 @@ VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6, const char *uds, struct vtp_cs vcs; const struct cp_methods *methods; - assert((uds != NULL && ip4 == NULL && ip6 == NULL) - || (uds == NULL && (ip4 != NULL || ip6 != NULL))); + assert((uds != NULL && ip4 == NULL && ip6 == NULL) || + (uds == NULL && (ip4 != NULL || ip6 != NULL))); INIT_OBJ(&vcs, VTP_CS_MAGIC); vcs.ip4 = ip4; vcs.ip6 = ip6; diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 12280e17a..30adf54a0 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -1132,7 +1132,7 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, ctx.ws = req->ws; } if (bo != NULL) { - if(req) + if (req) assert(method == VCL_MET_PIPE); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo->vcl, VCL_MAGIC); diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 4e5396963..9580a3247 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -103,8 +103,8 @@ vrt_priv_dynamic(VRT_CTX, struct vrt_privs *vps, uintptr_t id, VTAILQ_FOREACH(vp, &vps->privs, list) { CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC); - if (vp->vcl == ctx->vcl && vp->id == id - && vp->vmod_id == vmod_id) + if (vp->vcl == ctx->vcl && vp->id == id && + vp->vmod_id == vmod_id) return (vp->priv); } ALLOC_OBJ(vp, VRT_PRIV_MAGIC); diff --git a/bin/varnishd/mgt/mgt_acceptor.c b/bin/varnishd/mgt/mgt_acceptor.c index 8ef0f3aa9..fbf7f2619 100644 --- a/bin/varnishd/mgt/mgt_acceptor.c +++ b/bin/varnishd/mgt/mgt_acceptor.c @@ -102,8 +102,8 @@ mac_opensocket(struct listen_sock *ls) CHECK_OBJ(ls->perms, UDS_PERMS_MAGIC); assert(ls->uds); errno = 0; - if (ls->perms->mode != 0 - && chmod(ls->endpoint, ls->perms->mode) != 0) + if (ls->perms->mode != 0 && + chmod(ls->endpoint, ls->perms->mode) != 0) return errno; if (chown(ls->endpoint, ls->perms->uid, ls->perms->gid) != 0) return errno; @@ -265,8 +265,8 @@ MAC_Arg(const char *spec) la->name = name; if (*la->endpoint != '/' && strchr(la->endpoint, '/') != NULL) - ARGV_ERR("Unix domain socket addresses must be absolute paths " - "in -a (%s)\n", la->endpoint); + ARGV_ERR("Unix domain socket addresses must be" + " absolute paths in -a (%s)\n", la->endpoint); if (*la->endpoint == '/' && heritage.min_vcl < 41) heritage.min_vcl = 41; @@ -277,16 +277,16 @@ MAC_Arg(const char *spec) if ((eq = strchr(av[i], '=')) == NULL) { if (xp != NULL) - ARGV_ERR("Too many protocol sub-args in -a " - "(%s)\n", av[i]); + ARGV_ERR("Too many protocol sub-args" + " in -a (%s)\n", av[i]); xp = XPORT_Find(av[i]); if (xp == NULL) ARGV_ERR("Unknown protocol '%s'\n", av[i]); continue; } if (la->endpoint[0] != '/') - ARGV_ERR("Invalid sub-arg %s for IP addresses in -a\n", - av[i]); + ARGV_ERR("Invalid sub-arg %s for IP addresses" + " in -a\n", av[i]); val = eq + 1; len = eq - av[i]; diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c index 9ec6f84ec..5f821ac77 100644 --- a/bin/varnishd/proxy/cache_proxy_proto.c +++ b/bin/varnishd/proxy/cache_proxy_proto.c @@ -449,7 +449,7 @@ vpx_proto2(const struct worker *wrk, struct req *req) "PROXY2: Ignoring TLV"); return (0); } - switch(d[0]) { + switch (d[0]) { case PP2_TYPE_CRC32C: { uint32_t n_crc32c = vbe32dec(d+3); diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 53d32328c..62ac1d022 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -256,8 +256,7 @@ macro_expand(struct vtclog *vl, const char *text) NEEDLESS(return (NULL)); } VSB_printf(vsb, "${%.*s}", (int)(q - p), p); - } - else { + } else { VSB_printf(vsb, "%s", m); free(m); } diff --git a/lib/libvarnish/vsb.c b/lib/libvarnish/vsb.c index d95060838..0bc0925ab 100644 --- a/lib/libvarnish/vsb.c +++ b/lib/libvarnish/vsb.c @@ -544,8 +544,8 @@ VSB_quote_pfx(struct vsb *s, const char *pfx, const void *v, int len, int how) } if (!quote && !(how & (VSB_QUOTE_JSON|VSB_QUOTE_CSTR))) { (void)VSB_bcat(s, p, len); - if ((how & (VSB_QUOTE_UNSAFE|VSB_QUOTE_NONL)) - && p[len-1] != '\n') + if ((how & (VSB_QUOTE_UNSAFE|VSB_QUOTE_NONL)) && + p[len-1] != '\n') (void)VSB_putc(s, '\n'); return; } diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 17209dc4d..032a6e939 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -491,7 +491,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (extra == NULL) extra = ""; VTAILQ_INIT(&head); - for(;vv != NULL; vv = VTAILQ_NEXT(vv, list)) { + for (;vv != NULL; vv = VTAILQ_NEXT(vv, list)) { assert(vv->type == VJSN_ARRAY); fa = calloc(1, sizeof *fa); AN(fa); diff --git a/lib/libvmod_blob/url.c b/lib/libvmod_blob/url.c index 8ba47fcee..84f5d0f22 100644 --- a/lib/libvmod_blob/url.c +++ b/lib/libvmod_blob/url.c @@ -150,8 +150,8 @@ url_decode(const enum encoding dec, char *restrict const buf, } break; case PERCENT: - if (isoutofrange(*s) - || (nib = nibble[*s - '0']) == ILL) { + if (isoutofrange(*s) || + (nib = nibble[*s - '0']) == ILL) { errno = EINVAL; return -1; } @@ -162,8 +162,8 @@ url_decode(const enum encoding dec, char *restrict const buf, errno = ENOMEM; return -1; } - if (isoutofrange(*s) - || (nib2 = nibble[*s - '0']) == ILL) { + if (isoutofrange(*s) || + (nib2 = nibble[*s - '0']) == ILL) { errno = EINVAL; return -1; } diff --git a/lib/libvmod_debug/vmod_debug_obj.c b/lib/libvmod_debug/vmod_debug_obj.c index f0536016b..fcf74a740 100644 --- a/lib/libvmod_debug/vmod_debug_obj.c +++ b/lib/libvmod_debug/vmod_debug_obj.c @@ -128,6 +128,7 @@ xyzzy_obj_test_priv_call(VRT_CTX, (void)o; xyzzy_test_priv_call(ctx, priv); } + VCL_VOID v_matchproto_() xyzzy_obj_test_priv_vcl(VRT_CTX, struct xyzzy_debug_obj *o, struct vmod_priv *priv) @@ -135,6 +136,7 @@ xyzzy_obj_test_priv_vcl(VRT_CTX, (void)o; xyzzy_test_priv_vcl(ctx, priv); } + VCL_STRING v_matchproto_() xyzzy_obj_test_priv_task(VRT_CTX, struct xyzzy_debug_obj *o, struct vmod_priv *priv, VCL_STRING s) @@ -142,6 +144,7 @@ xyzzy_obj_test_priv_task(VRT_CTX, (void)o; return (xyzzy_test_priv_task(ctx, priv, s)); } + VCL_STRING v_matchproto_() xyzzy_obj_test_priv_top(VRT_CTX, struct xyzzy_debug_obj *o, struct vmod_priv *priv, VCL_STRING s) From fgsch at lodoss.net Thu Aug 16 08:52:25 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] 90db2adaf Plug harmless leak Message-ID: <20180816085225.2DD939866D@lists.varnish-cache.org> commit 90db2adaf8492b82ddf660e40e5d9b3d9bb9f11c Author: Federico G. Schwindt Date: Tue Mar 27 01:06:55 2018 -0300 Plug harmless leak diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 62ac1d022..1f724924a 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -460,7 +460,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir, { FILE *f; struct vsb *vsb; - const char *p; + char *p; (void)signal(SIGPIPE, SIG_IGN); @@ -474,8 +474,12 @@ exec_file(const char *fn, const char *script, const char *tmpdir, vsb = VSB_new_auto(); AN(vsb); - if (*fn != '/') - VSB_cat(vsb, macro_get("pwd", NULL)); + if (*fn != '/') { + p = macro_get("pwd", NULL); + AN(p); + VSB_cat(vsb, p); + free(p); + } p = strrchr(fn, '/'); if (p != NULL) { VSB_putc(vsb, '/'); From fgsch at lodoss.net Thu Aug 16 08:52:25 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] 3c90fdcc3 Typos and formatting Message-ID: <20180816085225.572C89868E@lists.varnish-cache.org> commit 3c90fdcc3a88989d1639b9ef482682a44fafee48 Author: Federico G. Schwindt Date: Tue Mar 27 08:53:16 2018 -0300 Typos and formatting diff --git a/lib/libvarnish/vsa.c b/lib/libvarnish/vsa.c index 1c05520ea..4e0762f95 100644 --- a/lib/libvarnish/vsa.c +++ b/lib/libvarnish/vsa.c @@ -91,7 +91,7 @@ * Along the way the BSD people figured out that it was a bother * to carry the length argument separately, and added that to the * format of sockaddr, but other groups found this unclean, as - * the length was already an explicit paramter. + * the length was already an explicit parameter. * * The net result of this is that your "portable" code, must take * care to handle the "sa_len" member on kernels which have it, diff --git a/lib/libvmod_blob/vmod.vcc b/lib/libvmod_blob/vmod.vcc index 341f3feb8..0a7e652d5 100644 --- a/lib/libvmod_blob/vmod.vcc +++ b/lib/libvmod_blob/vmod.vcc @@ -138,7 +138,7 @@ character ``=``. The ``BASE64URLNOPAD`` encoding uses the same alphabet as ``BASE6URL``, but leaves out the padding. Thus the length of an -encoding with this scheme is not necessarily a mutltiple of four. +encoding with this scheme is not necessarily a multiple of four. The ``case`` ENUM MUST be set to ``DEFAULT`` for for all of the ``BASE64*`` encodings. @@ -202,7 +202,7 @@ $Function STRING encode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} encoding="IDENTITY", ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT", BLOB blob) -Returns a string representation of the BLOB ``blob`` as specifed by +Returns a string representation of the BLOB ``blob`` as specified by ``encoding``. ``case`` determines the case of hex digits for the ``HEX`` and ``URL`` encodings, and is ignored for the other encodings. diff --git a/lib/libvmod_directors/vmod.vcc b/lib/libvmod_directors/vmod.vcc index 586c9dbe8..a1a625f58 100644 --- a/lib/libvmod_directors/vmod.vcc +++ b/lib/libvmod_directors/vmod.vcc @@ -78,7 +78,6 @@ Description Add a backend to the round-robin director. Example vdir.add_backend(backend1); - vdir.add_backend(backend2); $Method VOID .remove_backend(BACKEND) @@ -86,7 +85,6 @@ Description Remove a backend from the round-robin director. Example vdir.remove_backend(backend1); - vdir.remove_backend(backend2); $Method BACKEND .backend() @@ -121,7 +119,6 @@ Description Example vdir.add_backend(backend1); - vdir.add_backend(backend2); $Method VOID .remove_backend(BACKEND) @@ -129,7 +126,6 @@ Description Remove a backend from the director. Example vdir.remove_backend(backend1); - vdir.remove_backend(backend2); $Method BACKEND .backend() @@ -162,9 +158,9 @@ Description director. Example - # 2/3 to backend1, 1/3 to backend2. - vdir.add_backend(backend1, 10.0); - vdir.add_backend(backend2, 5.0); + | # 2/3 to backend1, 1/3 to backend2. + | vdir.add_backend(backend1, 10.0); + | vdir.add_backend(backend2, 5.0); $Method VOID .remove_backend(BACKEND) @@ -172,7 +168,6 @@ Description Remove a backend from the director. Example vdir.remove_backend(backend1); - vdir.remove_backend(backend2); $Method BACKEND .backend() @@ -205,7 +200,6 @@ Description Example vdir.add_backend(backend1, 1.0); - vdir.add_backend(backend2, 1.0); $Method VOID .remove_backend(BACKEND) @@ -213,7 +207,6 @@ Description Remove a backend from the director. Example vdir.remove_backend(backend1); - vdir.remove_backend(backend2); $Method BACKEND .backend(STRING_LIST) @@ -222,8 +215,8 @@ Description Use the string or list of strings provided to pick the backend. Example - # pick a backend based on the cookie header from the client - set req.backend_hint = vdir.backend(req.http.cookie); + | # pick a backend based on the cookie header from the client + | set req.backend_hint = vdir.backend(req.http.cookie); $Object shard() @@ -573,7 +566,7 @@ is _not_ the order given when backends are added. associated parameter set affect the sharding decision once the director resolves to an actual backend. - * If other paramter arguments are also given, they have preference + * If other parameter arguments are also given, they have preference and are kept even if the parameter set given by the `param` argument is subsequently changed within the same backend request. @@ -647,17 +640,17 @@ use. See `func_shard.backend`_. $Method INT .get_alt() -Get the `alt` paramter which a shard director using this parameter +Get the `alt` parameter which a shard director using this parameter object would use. See `func_shard.backend`_. $Method REAL .get_warmup() -Get the `warmup` paramter which a shard director using this parameter +Get the `warmup` parameter which a shard director using this parameter object would use. See `func_shard.backend`_. $Method BOOL .get_rampup() -Get the `rampup` paramter which a shard director using this parameter +Get the `rampup` parameter which a shard director using this parameter object would use. See `func_shard.backend`_. $Method STRING .get_healthy() diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index 9b42e5a54..168f15a81 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -86,7 +86,7 @@ struct vmod_directors_shard_param { const struct vmod_directors_shard_param *defaults; enum vmod_directors_shard_param_scope scope; - /* paramters */ + /* parameters */ enum by_e by; enum healthy_e healthy; uint32_t mask; From fgsch at lodoss.net Thu Aug 16 08:52:25 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] 39d6244ac Document do_g[un]zip wrt http_gzip_support Message-ID: <20180816085225.7A3A6986A6@lists.varnish-cache.org> commit 39d6244acfc19fdc646c0f9bbf3cefb6a3faecbe Author: Federico G. Schwindt Date: Tue Mar 27 09:02:12 2018 -0300 Document do_g[un]zip wrt http_gzip_support Addresses #2626. diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 253da0bea..c4ded7c3e 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -739,6 +739,9 @@ beresp.do_gzip Set to `true` to gzip the object while storing it. + If `http_gzip_support` is disabled, setting this variable + has no effect. + beresp.do_gunzip Type: BOOL @@ -752,6 +755,9 @@ beresp.do_gunzip Set to `true` to gunzip the object while storing it in the cache. + If `http_gzip_support` is disabled, setting this variable + has no effect. + beresp.was_304 Type: BOOL From phk at FreeBSD.org Thu Aug 16 08:52:25 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] 4abcaa49f Add support for testing HA-proxy Message-ID: <20180816085225.A270F986BB@lists.varnish-cache.org> commit 4abcaa49f109184d3de501c58f1abf3a7db1944e Author: Poul-Henning Kamp Date: Tue Mar 27 19:56:11 2018 +0000 Add support for testing HA-proxy Also a trivial coverage tes which runs if haproxy is in $PATH. Submitted by: Frederic Lecaille diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index efbac2ab8..c2c81d79b 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -33,6 +33,7 @@ varnishtest_SOURCES = \ vtc.c \ vtc_barrier.c \ vtc_client.c \ + vtc_haproxy.c \ vtc_h2_dectbl.h \ vtc_h2_enctbl.h \ vtc_h2_hpack.c \ diff --git a/bin/varnishtest/cmds.h b/bin/varnishtest/cmds.h index 58c2e7b45..290237d7e 100644 --- a/bin/varnishtest/cmds.h +++ b/bin/varnishtest/cmds.h @@ -34,7 +34,7 @@ CMD(client) CMD(delay) CMD(err_shell) CMD(feature) -//CMD(haproxy) +CMD(haproxy) CMD(logexpect) CMD(process) CMD(server) diff --git a/bin/varnishtest/programs.h b/bin/varnishtest/programs.h index 484900596..f8875ce31 100644 --- a/bin/varnishtest/programs.h +++ b/bin/varnishtest/programs.h @@ -27,6 +27,7 @@ * */ +VTC_PROG(haproxy) VTC_PROG(varnishadm) VTC_PROG(varnishd) VTC_PROG(varnishhist) diff --git a/bin/varnishtest/tests/README b/bin/varnishtest/tests/README index caadbd95f..35d598dd2 100644 --- a/bin/varnishtest/tests/README +++ b/bin/varnishtest/tests/README @@ -21,6 +21,7 @@ Naming scheme id ~ ^e --> ESI tests id ~ ^f --> Security related tests id ~ ^g --> GZIP tests + id ~ ^h --> HAproxy tests id ~ ^j --> JAIL tests id ~ ^l --> VSL tests id ~ ^m --> VMOD tests excluding director diff --git a/bin/varnishtest/tests/h00001.vtc b/bin/varnishtest/tests/h00001.vtc new file mode 100644 index 000000000..3c599a520 --- /dev/null +++ b/bin/varnishtest/tests/h00001.vtc @@ -0,0 +1,32 @@ +varnishtest "Basic HAproxy test" + +feature ignore_unknown_macro + +feature cmd {haproxy --version 2>&1 | grep -q 'HA-Proxy version'} + +server s1 { + rxreq + txresp -body "s1 >>> Hello world!" +} -start + +haproxy h1 -arg "-d" -conf { + defaults + mode http + timeout connect 5s + timeout server 30s + timeout client 30s + + backend be1 + server srv1 ${s1_addr}:${s1_port} + + frontend http1 + use_backend be1 + bind "fd@${fe1}" +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.body == "s1 >>> Hello world!" +} -run diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c new file mode 100644 index 000000000..17c62fb1f --- /dev/null +++ b/bin/varnishtest/vtc_haproxy.c @@ -0,0 +1,616 @@ +/*- + * Copyright (c) 2008-2018 Varnish Software AS + * All rights reserved. + * + * Author: Fr?d?ric L?caille + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "vtc.h" + +#include "vav.h" +#include "vfil.h" +#include "vpf.h" +#include "vtcp.h" +#include "vtim.h" + +#define HAPROXY_PROGRAM_ENV_VAR "HAPROXY_PROGRAM" +#define HAPROXY_OPT_WORKER "-W" +#define HAPROXY_OPT_DAEMON "-D" +#define HAPROXY_OPT_CHECK_MODE "-c" +#define HAPROXY_SIGNAL SIGINT +#define HAPROXY_EXPECT_EXIT (128 + HAPROXY_SIGNAL) + +struct haproxy { + unsigned magic; +#define HAPROXY_MAGIC 0x8a45cf75 + char *name; + struct vtclog *vl; + VTAILQ_ENTRY(haproxy) list; + + char *filename; + struct vsb *args; + int opt_worker; + int opt_daemon; + int opt_check_mode; + char *pid_fn; + pid_t pid; + pid_t ppid; + int fds[4]; + char *cfg_fn; + + pthread_t tp; + int expect_exit; + int expect_signal; + int kill_status; + int kill_errno; + + const char *cli_fn; + + char *workdir; +}; + +static void haproxy_cleanup(struct haproxy *h, int is_haproxy_listener); + +static VTAILQ_HEAD(, haproxy) haproxies = + VTAILQ_HEAD_INITIALIZER(haproxies); + +/********************************************************************** + * + */ + +static void +wait_stopped(struct haproxy *h) +{ + vtc_log(h->vl, 3, "wait-stopped"); + while (1) { + if (h->kill_status >= 0 || h->kill_errno == ESRCH) + break; + + usleep(1000); + h->kill_status = kill(h->pid, 0); + h->kill_errno = errno; + } +} + +static void +wait_running(struct haproxy *h) +{ + char buf_err[1024] = {0}; + int usleep_time = 1000; + double t0; + pid_t pid; + + if (h->opt_check_mode) + return; + + if (h->pid_fn == NULL) { + /* + * If we use no pid-file, check that the process + * we started is still running. + */ + if (kill(h->pid, 0) < 0) + vtc_fatal(h->vl, "Process %ld not there: %s", + (long)h->pid, strerror(errno)); + return; + } + + vtc_log(h->vl, 3, "wait-running"); + for (t0 = VTIM_mono(); VTIM_mono() - t0 < 3;) { + if (vtc_error) + return; + + if (VPF_read(h->pid_fn, &pid) != 0) { + bprintf(buf_err, + "Could not read PID file '%s'", h->pid_fn); + usleep(usleep_time); + continue; + } + + if (!h->opt_daemon && pid != h->pid) { + bprintf(buf_err, + "PID file has different PID (%ld != %lld)", + (long)pid, (long long)h->pid); + usleep(usleep_time); + continue; + } + + if (kill(pid, 0) < 0) { + bprintf(buf_err, + "Could not find PID %ld process", (long)pid); + usleep(usleep_time); + continue; + } + + h->pid = pid; + + vtc_log(h->vl, 2, "haproxy PID %ld successfully started", + (long)pid); + return; + } + vtc_fatal(h->vl, "haproxy %s PID file check failed:\n\t%s\n", + h->name, buf_err); +} + +/********************************************************************** + * Allocate and initialize a haproxy + */ + +static struct haproxy * +haproxy_new(const char *name) +{ + struct haproxy *h; + struct vsb *vsb; + char buf[PATH_MAX]; + + ALLOC_OBJ(h, HAPROXY_MAGIC); + AN(h); + REPLACE(h->name, name); + + h->args = VSB_new_auto(); + + h->vl = vtc_logopen(name); + AN(h->vl); + + h->filename = getenv(HAPROXY_PROGRAM_ENV_VAR); + if (h->filename == NULL) + REPLACE(h->filename, "haproxy"); + + bprintf(buf, "${tmpdir}/%s", name); + vsb = macro_expand(h->vl, buf); + AN(vsb); + h->workdir = strdup(VSB_data(vsb)); + AN(h->workdir); + VSB_destroy(&vsb); + + bprintf(buf, "%s/stats.sock", h->workdir); + h->cli_fn = strdup(buf); + AN(h->cli_fn); + + bprintf(buf, "%s/cfg", h->workdir); + h->cfg_fn = strdup(buf); + AN(h->cfg_fn); + + VSB_printf(h->args, "-f %s ", h->cfg_fn); + + bprintf(buf, "rm -rf %s ; mkdir -p %s", h->workdir, h->workdir); + AZ(system(buf)); + + VTAILQ_INSERT_TAIL(&haproxies, h, list); + + return (h); +} + +/********************************************************************** + * Delete a haproxy instance + */ + +static void +haproxy_delete(struct haproxy *h) +{ + char buf[PATH_MAX]; + + CHECK_OBJ_NOTNULL(h, HAPROXY_MAGIC); + vtc_logclose(h->vl); + + if (!leave_temp) { + bprintf(buf, "rm -rf %s", h->workdir); + AZ(system(buf)); + } + + free(h->name); + free(h->workdir); + VSB_destroy(&h->args); + + /* XXX: MEMLEAK (?) */ + FREE_OBJ(h); +} + +/********************************************************************** + * HAProxy listener + */ + +static void * +haproxy_thread(void *priv) +{ + struct haproxy *h; + + CAST_OBJ_NOTNULL(h, priv, HAPROXY_MAGIC); + return (vtc_record(h->vl, h->fds[0])); +} + +/********************************************************************** + * Start a HAProxy instance. + */ + +static void +haproxy_start(struct haproxy *h) +{ + char **argv; + int i; + char buf[PATH_MAX]; + struct vsb *vsb; + + vtc_log(h->vl, 2, "%s", __func__); + + AZ(VSB_finish(h->args)); + argv = VAV_Parse(VSB_data(h->args), NULL, 0); + AN(argv); + if (argv[0] != NULL) + vtc_fatal(h->vl, "Could not parse argv-string: %s", argv[0]); + for (i = 1; argv[i] != NULL; i++) { + /* Check if HAPROXY_OPT_WORKER option was provided. */ + if (!strcmp(argv[i], HAPROXY_OPT_WORKER)) { + h->opt_worker = 1; + } else if (!strcmp(argv[i], HAPROXY_OPT_DAEMON)) { + h->opt_daemon = 1; + } else if (!strcmp(argv[i], HAPROXY_OPT_CHECK_MODE)) { + h->opt_check_mode = 1; + } + } + VAV_Free(argv); + vtc_log(h->vl, 4, "opt_worker %d opt_daemon %d opt_check_mode %d", + h->opt_worker, h->opt_daemon, h->opt_check_mode); + + vsb = VSB_new_auto(); + AN(vsb); + VSB_printf(vsb, "%s %s", h->filename, VSB_data(h->args)); + + if (h->opt_worker || h->opt_daemon) { + bprintf(buf, "%s/pid", h->workdir); + h->pid_fn = strdup(buf); + AN(h->pid_fn); + VSB_printf(vsb, " -p %s", h->pid_fn); + } + + AZ(VSB_finish(vsb)); + vtc_dump(h->vl, 4, "argv", VSB_data(vsb), -1); + + if (h->opt_worker && !h->opt_daemon) { + /* + * HAProxy master process must exit with status 128 + + * if signaled by signal. + */ + h->expect_exit = HAPROXY_EXPECT_EXIT; + } else { + h->expect_exit = 0; + } + + AZ(pipe(&h->fds[0])); + AZ(pipe(&h->fds[2])); + h->pid = h->ppid = fork(); + assert(h->pid >= 0); + if (h->pid == 0) { + AZ(chdir(h->name)); + AZ(dup2(h->fds[0], 0)); + assert(dup2(h->fds[3], 1) == 1); + assert(dup2(1, 2) == 2); + closefd(&h->fds[0]); + closefd(&h->fds[1]); + closefd(&h->fds[2]); + closefd(&h->fds[3]); + AZ(execl("/bin/sh", "/bin/sh", "-c", VSB_data(vsb), NULL)); + exit(1); + } + VSB_destroy(&vsb); + + vtc_log(h->vl, 3, "PID: %ld", (long)h->pid); + macro_def(h->vl, h->name, "pid", "%ld", (long)h->pid); + macro_def(h->vl, h->name, "name", "%s", h->workdir); + + closefd(&h->fds[0]); + closefd(&h->fds[3]); + h->fds[0] = h->fds[2]; + h->fds[2] = h->fds[3] = -1; + + AZ(pthread_create(&h->tp, NULL, haproxy_thread, h)); + + wait_running(h); +} + +/********************************************************************** + * Stop a HAProxy + */ + +static void +haproxy_stop(struct haproxy *h) +{ + if (h->opt_check_mode) + return; + + if (h->pid < 0) + haproxy_start(h); + + vtc_log(h->vl, 2, "Stop"); + h->kill_status = kill(h->pid, HAPROXY_SIGNAL); + h->kill_errno = errno; + h->expect_signal = -HAPROXY_SIGNAL; + + wait_stopped(h); +} + +/********************************************************************** + * Cleanup + */ + +static void +haproxy_cleanup(struct haproxy *h, int is_haproxy_listener) +{ + void *p; + + vtc_log(h->vl, 2, "%s (%d)", __func__, is_haproxy_listener); + if (!is_haproxy_listener) { + /* Close the STDIN connection. */ + closefd(&h->fds[1]); + + /* Wait until STDOUT+STDERR closes */ + AZ(pthread_join(h->tp, &p)); + closefd(&h->fds[0]); + if (h->opt_daemon) + return; + } + + if (h->ppid == -1) + return; + + vtc_wait4(h->vl, h->ppid, h->expect_exit, h->expect_signal, 0); + h->ppid = -1; +} + +/********************************************************************** + * Wait for a HAProxy instance. + */ + +static void +haproxy_wait(struct haproxy *h) +{ + if (h->pid < 0) + return; + + vtc_log(h->vl, 2, "Wait"); + + haproxy_stop(h); + + haproxy_cleanup(h, 0); +} + +#define HAPROXY_BE_FD_STR "fd@${" +#define HAPROXY_BE_FD_STRLEN strlen(HAPROXY_BE_FD_STR) + +static int +haproxy_build_backends(const struct haproxy *h, const char *vsb_data) +{ + char *s, *p, *q; + + s = strdup(vsb_data); + if (!s) + return -1; + + p = s; + while (1) { + int sock; + char buf[128], addr[128], port[128]; + const char *err; + + p = strstr(p, HAPROXY_BE_FD_STR); + if (!p) + break; + + q = p += HAPROXY_BE_FD_STRLEN; + while (*q && *q != '}') + q++; + if (*q != '}') + break; + + *q++ = '\0'; + sock = VTCP_listen_on(":0", NULL, 1, &err); + if (err != NULL) + vtc_fatal(h->vl, + "Create listen socket failed: %s", err); + + VTCP_myname(sock, addr, sizeof addr, port, sizeof port); + bprintf(buf, "%s_%s", h->name, p); + macro_def(h->vl, buf, "sock", "%s %s", addr, port); + macro_def(h->vl, buf, "addr", "%s", addr); + macro_def(h->vl, buf, "port", "%s", port); + + bprintf(buf, "%d", sock); + vtc_log(h->vl, 4, "setenv(%s, %s)", p, buf); + if (setenv(p, buf, 0) == -1) + vtc_fatal(h->vl, "setenv() failed: %s (%d)", + strerror(errno), errno); + p = q; + } + free(s); + return (0); +} + +/********************************************************************** + * Write a configuration for HAProxy instance. + */ + +static void +haproxy_write_conf(const struct haproxy *h, const char *cfg) +{ + struct vsb *vsb, *vsb2; + + vsb = VSB_new_auto(); + AN(vsb); + + vsb2 = VSB_new_auto(); + AN(vsb2); + + VSB_printf(vsb, " global\n\tstats socket %s " + "level admin mode 600\n", h->cli_fn); + AZ(VSB_cat(vsb, cfg)); + AZ(VSB_finish(vsb)); + + AZ(haproxy_build_backends(h, VSB_data(vsb))); + + if (VFIL_writefile(h->workdir, h->cfg_fn, + VSB_data(vsb), VSB_len(vsb)) != 0) + vtc_fatal(h->vl, + "failed to write haproxy configuration file: %s (%d)", + strerror(errno), errno); + + vtc_dump(h->vl, 4, "conf", VSB_data(vsb), VSB_len(vsb)); + + VSB_destroy(&vsb2); + VSB_destroy(&vsb); +} + +/* SECTION: haproxy haproxy + * + * Define and interact with haproxy instances. + * + * To define a haproxy server, you'll use this syntax:: + * + * haproxy hNAME [-arg STRING] [-conf STRING] + * + * The first ``haproxy hNAME`` invocation will start the haproxy master + * process in the background, waiting for the ``-start`` switch to actually + * start the child. + * + * Arguments: + * + * hNAME + * Identify the HAProxy server with a string, it must starts with 'h'. + * + * \-arg STRING + * Pass an argument to haproxy, for example "-h simple_list". + * + * \-conf STRING + * Specify the configuration to be loaded by this HAProxy instance. + * + * You can decide to start the HAProxy instance and/or wait for several events:: + * + * haproxy hNAME [-start] [-wait-running] [-wait-stopped] + * + * \-start + * Start this HAProxy instance. + * + * \-stop + * Stop this HAProxy instance. + * + * \-wait-running + * Wait for that instance to terminate. + * + * \-wait-stopped + * Wait for that instance to terminate. + * + * \-cleanup + * Once HAProxy is stopped, clean everything after it. This is only used + * in very few tests and you should never need it. + * + * \-expectexit NUMBER + * Expect haproxy to exit(3) with this value + * + */ + +void +cmd_haproxy(CMD_ARGS) +{ + struct haproxy *h, *h2; + + (void)priv; + (void)cmd; + + if (av == NULL) { + /* Reset and free */ + VTAILQ_FOREACH_SAFE(h, &haproxies, list, h2) { + vtc_log(h->vl, 2, + "Reset and free %s haproxy %d", h->name, h->pid); + if (h->pid >= 0) + haproxy_wait(h); + VTAILQ_REMOVE(&haproxies, h, list); + haproxy_delete(h); + } + return; + } + + AZ(strcmp(av[0], "haproxy")); + av++; + + VTC_CHECK_NAME(vl, av[0], "haproxy", 'h'); + VTAILQ_FOREACH(h, &haproxies, list) + if (!strcmp(h->name, av[0])) + break; + if (h == NULL) + h = haproxy_new(av[0]); + av++; + + for (; *av != NULL; av++) { + if (vtc_error) + break; + if (!strcmp(*av, "-arg")) { + AN(av[1]); + AZ(h->pid); + VSB_cat(h->args, " "); + VSB_cat(h->args, av[1]); + av++; + continue; + } + if (!strcmp(*av, "-cleanup")) { + AZ(av[1]); + haproxy_cleanup(h, 0); + continue; + } + if (!strcmp(*av, "-conf")) { + AN(av[1]); + haproxy_write_conf(h, av[1]); + av++; + continue; + } + if (!strcmp(*av, "-expectexit")) { + h->expect_exit = strtoul(av[1], NULL, 0); + av++; + continue; + } + if (!strcmp(*av, "-start")) { + haproxy_start(h); + continue; + } + if (!strcmp(*av, "-stop")) { + haproxy_stop(h); + continue; + } + if (!strcmp(*av, "-wait-stopped")) { + wait_stopped(h); + continue; + } + if (!strcmp(*av, "-wait-running")) { + wait_running(h); + continue; + } + vtc_fatal(h->vl, "Unknown haproxy argument: %s", *av); + } +} diff --git a/bin/varnishtest/vtc_subr.c b/bin/varnishtest/vtc_subr.c index 39cafbefe..e232f95de 100644 --- a/bin/varnishtest/vtc_subr.c +++ b/bin/varnishtest/vtc_subr.c @@ -160,14 +160,15 @@ vtc_wait4(struct vtclog *vl, long pid, if (r < 0) vtc_fatal(vl, "wait4 failed on pid %ld: %s", pid, strerror(errno)); - vtc_log(vl, 2, "WAIT4 pid=%ld r=%d status=0x%04x (user %.6f sys %.6f)", - pid, r, status, + assert(r == pid); + vtc_log(vl, 2, "WAIT4 pid=%ld status=0x%04x (user %.6f sys %.6f)", + pid, status, ru.ru_utime.tv_sec + 1e-6 * ru.ru_utime.tv_usec, ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec ); if (WIFEXITED(status) && expect_signal <= 0 && - (WEXITSTATUS(status) == expect_status)) + WEXITSTATUS(status) == expect_status) return; if (expect_signal < 0) From phk at FreeBSD.org Thu Aug 16 08:52:25 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] 57223773d Use (char*)0 because because GCC thinks NULL is something else ? Message-ID: <20180816085225.C8560986D1@lists.varnish-cache.org> commit 57223773d9237f3e44c3034bb2cac8c5c6a2b712 Author: Poul-Henning Kamp Date: Tue Mar 27 20:09:44 2018 +0000 Use (char*)0 because because GCC thinks NULL is something else ? diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 17c62fb1f..4f9ab5a4f 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -318,7 +318,7 @@ haproxy_start(struct haproxy *h) closefd(&h->fds[1]); closefd(&h->fds[2]); closefd(&h->fds[3]); - AZ(execl("/bin/sh", "/bin/sh", "-c", VSB_data(vsb), NULL)); + AZ(execl("/bin/sh", "/bin/sh", "-c", VSB_data(vsb), (char*)0)); exit(1); } VSB_destroy(&vsb); From phk at FreeBSD.org Thu Aug 16 08:52:25 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:25 +0000 (UTC) Subject: [6.0] ad5d4de5e Printf pid using cast and %ld Message-ID: <20180816085225.EBD7E986E3@lists.varnish-cache.org> commit ad5d4de5efa3be2344c21b43aea64e80251da4ec Author: Poul-Henning Kamp Date: Tue Mar 27 20:18:47 2018 +0000 Printf pid using cast and %ld diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 4f9ab5a4f..d97ffb47d 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -548,7 +548,8 @@ cmd_haproxy(CMD_ARGS) /* Reset and free */ VTAILQ_FOREACH_SAFE(h, &haproxies, list, h2) { vtc_log(h->vl, 2, - "Reset and free %s haproxy %d", h->name, h->pid); + "Reset and free %s haproxy %ld", + h->name, (long)h->pid); if (h->pid >= 0) haproxy_wait(h); VTAILQ_REMOVE(&haproxies, h, list); From phk at FreeBSD.org Thu Aug 16 08:52:26 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:26 +0000 (UTC) Subject: [6.0] 4438bf419 Allow a single '\n' after the PID Message-ID: <20180816085226.1F4CC986F3@lists.varnish-cache.org> commit 4438bf419db814842534247c8aaa0284592f865a Author: Poul-Henning Kamp Date: Wed Mar 28 14:15:33 2018 +0000 Allow a single '\n' after the PID diff --git a/lib/libvarnish/vpf.c b/lib/libvarnish/vpf.c index 915a028ec..cf326fb02 100644 --- a/lib/libvarnish/vpf.c +++ b/lib/libvarnish/vpf.c @@ -89,6 +89,8 @@ VPF_read(const char *path, pid_t *pidptr) return (error); else if (i == 0) return (EAGAIN); + if (i > 0 && buf[i - 1] == '\n') + i--; buf[i] = '\0'; *pidptr = strtol(buf, &endptr, 10); From phk at FreeBSD.org Thu Aug 16 08:52:26 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:26 +0000 (UTC) Subject: [6.0] a056f9981 Migrate the shell PID to haproxy where we want it. Message-ID: <20180816085226.482F8986FF@lists.varnish-cache.org> commit a056f9981e23d16f17e3149dd2c0fa23b29ba0ae Author: Poul-Henning Kamp Date: Wed Mar 28 14:16:00 2018 +0000 Migrate the shell PID to haproxy where we want it. diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index d97ffb47d..e3ea8d22d 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -283,7 +283,7 @@ haproxy_start(struct haproxy *h) vsb = VSB_new_auto(); AN(vsb); - VSB_printf(vsb, "%s %s", h->filename, VSB_data(h->args)); + VSB_printf(vsb, "exec %s %s", h->filename, VSB_data(h->args)); if (h->opt_worker || h->opt_daemon) { bprintf(buf, "%s/pid", h->workdir); From phk at FreeBSD.org Thu Aug 16 08:52:26 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:26 +0000 (UTC) Subject: [6.0] 082e6bc51 Add a test with HAproxy in daemonmode (if available) Message-ID: <20180816085226.6E2469870A@lists.varnish-cache.org> commit 082e6bc51f2cefaa557e32f312727afe1bdab909 Author: Poul-Henning Kamp Date: Wed Mar 28 14:16:43 2018 +0000 Add a test with HAproxy in daemonmode (if available) diff --git a/bin/varnishtest/tests/h00002.vtc b/bin/varnishtest/tests/h00002.vtc new file mode 100644 index 000000000..6e2af6651 --- /dev/null +++ b/bin/varnishtest/tests/h00002.vtc @@ -0,0 +1,32 @@ +varnishtest "Basic HAproxy test (daemon mode)" + +feature ignore_unknown_macro + +feature cmd {haproxy --version 2>&1 | grep -q 'HA-Proxy version'} + +server s1 { + rxreq + txresp -body "s1 >>> Hello world!" +} -start + +haproxy h1 -arg "-D" -conf { + defaults + mode http + timeout connect 5s + timeout server 30s + timeout client 30s + + backend be1 + server srv1 ${s1_addr}:${s1_port} + + frontend http1 + use_backend be1 + bind "fd@${fe1}" +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.body == "s1 >>> Hello world!" +} -run From phk at FreeBSD.org Thu Aug 16 08:52:26 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:26 +0000 (UTC) Subject: [6.0] 296814e74 Don't unlock the mutex unless we locked it. Message-ID: <20180816085226.964439871C@lists.varnish-cache.org> commit 296814e74b9862213a0f884b9366bbc2d12490e9 Author: Poul-Henning Kamp Date: Wed Mar 28 15:21:09 2018 +0000 Don't unlock the mutex unless we locked it. It is only during cleanup, so this *may* be an adequate bandaid. diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c index f7f68af59..035e6b20a 100644 --- a/bin/varnishtest/vtc_barrier.c +++ b/bin/varnishtest/vtc_barrier.c @@ -422,7 +422,8 @@ cmd_barrier(CMD_ARGS) default: WRONG("Wrong barrier type"); } - AZ(pthread_mutex_unlock(&b->mtx)); + if (r == 0) + AZ(pthread_mutex_unlock(&b->mtx)); } return; } From phk at FreeBSD.org Thu Aug 16 08:52:26 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:26 +0000 (UTC) Subject: [6.0] dadc85271 We don't want distcheck to exercise persistent by default, but we do want VTEST to do so. Message-ID: <20180816085226.BC07F98726@lists.varnish-cache.org> commit dadc85271fe77deaf691cc46dcc95e15c2d5d419 Author: Poul-Henning Kamp Date: Wed Mar 28 21:25:07 2018 +0000 We don't want distcheck to exercise persistent by default, but we do want VTEST to do so. diff --git a/Makefile.am b/Makefile.am index 006c770ee..f019082a2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,7 @@ EXTRA_DIST = \ varnish.m4 \ varnish-legacy.m4 -DISTCHECK_CONFIGURE_FLAGS = \ +AM_DISTCHECK_CONFIGURE_FLAGS = \ --enable-developer-warnings \ --enable-debugging-symbols \ --enable-dependency-tracking \ diff --git a/tools/vtest.sh b/tools/vtest.sh index b2e121df6..92020396e 100755 --- a/tools/vtest.sh +++ b/tools/vtest.sh @@ -131,7 +131,7 @@ makedistcheck () ( set -e cd "${SRCDIR}" nice make vtest-clean - nice make distcheck + nice make distcheck DISTCHECK_CONFIGURE_FLAGS=--with-persistent-storage ) gcovtest () ( From fgsch at lodoss.net Thu Aug 16 08:52:26 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:26 +0000 (UTC) Subject: [6.0] 4edafdffe Sync with reality Message-ID: <20180816085226.E2E3D98734@lists.varnish-cache.org> commit 4edafdffe1c2057a95e5a0f74a99291355d5f1df Author: Federico G. Schwindt Date: Tue Mar 27 20:45:24 2018 -0300 Sync with reality diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c index 55294e8cf..06b01676c 100644 --- a/bin/varnishtest/vtc_misc.c +++ b/bin/varnishtest/vtc_misc.c @@ -342,7 +342,7 @@ cmd_delay(CMD_ARGS) * Do not fail the test if a string of the form ${...} is not * recognized as a macro. * term - * Support for ADM3A terminal + * Support for ansi.sys terminal * * persistent_storage * Varnish was built with the deprecated persistent storage. From fgsch at lodoss.net Thu Aug 16 08:52:27 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:27 +0000 (UTC) Subject: [6.0] 65d0c0c39 Formatting Message-ID: <20180816085227.152139874A@lists.varnish-cache.org> commit 65d0c0c395aaeadfe0f8344ad30caa0086c7e094 Author: Federico G. Schwindt Date: Tue Mar 27 20:48:59 2018 -0300 Formatting diff --git a/lib/libvmod_directors/vmod.vcc b/lib/libvmod_directors/vmod.vcc index a1a625f58..cc5f9aed2 100644 --- a/lib/libvmod_directors/vmod.vcc +++ b/lib/libvmod_directors/vmod.vcc @@ -339,16 +339,13 @@ when configuring the shard director, you are advised to check:: $Method VOID .set_warmup(REAL probability=0.0) Set the default warmup probability. See the `warmup` parameter of -``shard.backend()``. - -Default: 0.0 (no warmup) +``shard.backend()``. If probability is 0.0 (default), warmup is +disabled. $Method VOID .set_rampup(DURATION duration=0) Set the default rampup duration. See `rampup` parameter of -`shard.backend()`. - -Default: 0s (no rampup) +`shard.backend()`. If duration is 0 (default), rampup is disabled. $Method VOID .associate(BLOB param=0) @@ -415,13 +412,13 @@ To generate sharding keys using other hashes, use a custom vmod like .. _vmod blobdigest: https://code.uplex.de/uplex-varnish/libvmod-blobdigest/blob/master/README.rst $Method BACKEND .backend( - [ ENUM {HASH, URL, KEY, BLOB} by ], + [ ENUM {HASH, URL, KEY, BLOB} by=HASH ], [ INT key ], [ BLOB key_blob ], - [ INT alt ], - [ REAL warmup ], - [ BOOL rampup ], - [ ENUM {CHOSEN, IGNORE, ALL} healthy ], + [ INT alt=0 ], + [ REAL warmup=-1 ], + [ BOOL rampup=1 ], + [ ENUM {CHOSEN, IGNORE, ALL} healthy=CHOSEN ], [ BLOB param ], [ ENUM {NOW, LAZY} resolve] ) @@ -436,8 +433,6 @@ is _not_ the order given when backends are added. * `by` how to determine the sharding key - default: `HASH` - * `HASH`: * when called in backend context: Use the varnish hash value as @@ -451,21 +446,19 @@ is _not_ the order given when backends are added. * `BLOB`: use the `key_blob` argument - * `key` lookup key with `by=KEY` +* `key` lookup key with `by=KEY` - the `shard.key()` function may come handy to generate a sharding - key from custom strings. + the `shard.key()` function may come handy to generate a sharding + key from custom strings. - * `key_blob` lookup key with `by=BLOB` +* `key_blob` lookup key with `by=BLOB` - Currently, this uses the first 4 bytes from the given blob in - network byte order (big endian), left-padded with zeros for blobs - smaller than 4 bytes. + Currently, this uses the first 4 bytes from the given blob in + network byte order (big endian), left-padded with zeros for blobs + smaller than 4 bytes. * `alt` alternative backend selection - default: `0` - Select the `alt`-th alternative backend for the given `key`. This is particularly useful for retries / restarts due to backend @@ -476,8 +469,6 @@ is _not_ the order given when backends are added. * `rampup` slow start for servers which just went healthy - default: `true` - If `alt==0` and the chosen backend is in its rampup period, with a probability proportional to the fraction of time since the backup became healthy to the rampup period, return the next alternative @@ -491,8 +482,6 @@ is _not_ the order given when backends are added. possible values: -1, 0..1 - default: `-1` - `-1`: use the warmup probability from the director definition Only used for `alt==0`: Sets the ratio of requests (0.0 to 1.0) that @@ -505,8 +494,6 @@ is _not_ the order given when backends are added. * `healthy` - default: `CHOSEN` - * CHOSEN: Return a healthy backend if possible. For `alt==0`, return the first healthy backend or none. From fgsch at lodoss.net Thu Aug 16 08:52:27 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:27 +0000 (UTC) Subject: [6.0] 074d66ad4 Tighten up tests Message-ID: <20180816085227.46C3698764@lists.varnish-cache.org> commit 074d66ad49f7fa3b8fda6a23e9d1ad734842be5a Author: Federico G. Schwindt Date: Wed Mar 28 17:09:55 2018 -0300 Tighten up tests Prep work for upcoming change. diff --git a/bin/varnishtest/tests/b00012.vtc b/bin/varnishtest/tests/b00012.vtc index 224bd1ad6..6f81802ea 100644 --- a/bin/varnishtest/tests/b00012.vtc +++ b/bin/varnishtest/tests/b00012.vtc @@ -12,7 +12,7 @@ server s1 { varnish v1 -vcl+backend {} -start client c1 { - send "GET /foo HTTP/1.1\n\nGET /bar HTTP/1.1\n\nGET /bar HTTP/1.1\n\n" + send "GET /foo HTTP/1.1\nHost: foo\n\nGET /bar HTTP/1.1\nHost: foo\n\nGET /bar HTTP/1.1\nHost: foo\n\n" rxresp expect resp.status == 200 expect resp.bodylen == 3 diff --git a/bin/varnishtest/tests/b00013.vtc b/bin/varnishtest/tests/b00013.vtc index ffae946df..46f564145 100644 --- a/bin/varnishtest/tests/b00013.vtc +++ b/bin/varnishtest/tests/b00013.vtc @@ -16,17 +16,17 @@ varnish v1 -cli "param.set accept_filter false" varnish v1 -start client c1 { - send "GET /foo HTTP/1.1\r\n\r\nGET " + send "GET /foo HTTP/1.1\r\nHost: foo\r\n\r\nGET " rxresp expect resp.status == 200 expect resp.bodylen == 3 expect resp.http.x-varnish == "1001" - send "/bar HTTP/1.1\n\nGET /bar " + send "/bar HTTP/1.1\nHost: foo\n\nGET /bar " rxresp expect resp.status == 200 expect resp.bodylen == 6 expect resp.http.x-varnish == "1003" - send "HTTP/1.1\n\n" + send "HTTP/1.1\nHost: foo\n\n" rxresp expect resp.status == 200 expect resp.bodylen == 6 diff --git a/bin/varnishtest/tests/b00040.vtc b/bin/varnishtest/tests/b00040.vtc index 228aaa993..8d5db1525 100644 --- a/bin/varnishtest/tests/b00040.vtc +++ b/bin/varnishtest/tests/b00040.vtc @@ -46,28 +46,28 @@ delay .1 client c1 { send "GET /4 HTTP/1.1\r\n" - send "\r\n" + send "Host: foo\r\n\r\n" rxresp expect resp.status == 200 } -run delay .1 client c1 { - send "GET /5 HTTP/1.1\r\nHost: localhost\r\nBogo: Header\001More\r\n\r\n" + send "GET /5 HTTP/1.1\r\nHost: foo\r\nBogo: Header\001More\r\n\r\n" rxresp expect resp.status == 400 } -run delay .1 client c1 { - send "GET /6 HTTP/1.1\r\nHost: localhost\r\nBogo: Header\r\r\n\r\n" + send "GET /6 HTTP/1.1\r\nHost: foo\r\nBogo: Header\r\r\n\r\n" rxresp expect resp.status == 400 } -run delay .1 client c1 { - send "GET /7 HTTP/1.1\r\nHost: localhost\r\nBogo: Header\rMore\r\n\r\n" + send "GET /7 HTTP/1.1\r\nHost: foo\r\nBogo: Header\rMore\r\n\r\n" rxresp expect resp.status == 400 } -run diff --git a/bin/varnishtest/tests/b00055.vtc b/bin/varnishtest/tests/b00055.vtc index bb3a36df6..076eb1b06 100644 --- a/bin/varnishtest/tests/b00055.vtc +++ b/bin/varnishtest/tests/b00055.vtc @@ -12,7 +12,7 @@ server s1 { varnish v1 -arg "-a ${tmpdir}/v1.sock" -vcl+backend {} -start client c1 -connect "${tmpdir}/v1.sock" { - send "GET /foo HTTP/1.1\n\nGET /bar HTTP/1.1\n\nGET /bar HTTP/1.1\n\n" + send "GET /foo HTTP/1.1\nHost: foo\n\nGET /bar HTTP/1.1\nHost: foo\n\nGET /bar HTTP/1.1\nHost: foo\n\n" rxresp expect resp.status == 200 expect resp.bodylen == 3 diff --git a/bin/varnishtest/tests/b00056.vtc b/bin/varnishtest/tests/b00056.vtc index b875f0b77..4da3c7c67 100644 --- a/bin/varnishtest/tests/b00056.vtc +++ b/bin/varnishtest/tests/b00056.vtc @@ -16,17 +16,17 @@ varnish v1 -cli "param.set accept_filter false" varnish v1 -start client c1 -connect "${tmpdir}/v1.sock" { - send "GET /foo HTTP/1.1\r\n\r\nGET " + send "GET /foo HTTP/1.1\r\nHost: foo\r\n\r\nGET " rxresp expect resp.status == 200 expect resp.bodylen == 3 expect resp.http.x-varnish == "1001" - send "/bar HTTP/1.1\n\nGET /bar " + send "/bar HTTP/1.1\nHost: foo\n\nGET /bar " rxresp expect resp.status == 200 expect resp.bodylen == 6 expect resp.http.x-varnish == "1003" - send "HTTP/1.1\n\n" + send "HTTP/1.1\nHost: foo\n\n" rxresp expect resp.status == 200 expect resp.bodylen == 6 diff --git a/bin/varnishtest/tests/c00018.vtc b/bin/varnishtest/tests/c00018.vtc index 96368b931..7a27755ff 100644 --- a/bin/varnishtest/tests/c00018.vtc +++ b/bin/varnishtest/tests/c00018.vtc @@ -55,9 +55,8 @@ logexpect l1 -v v1 -g raw { expect 0 1003 ReqMethod {^POST$} expect 0 1003 ReqURL {^/$} expect 0 1003 ReqProtocol {^HTTP/1.1$} - expect 0 1003 ReqHeader {^Content-Length: 20$} - expect 0 1003 ReqHeader {^X-Forwarded-For:} - expect 0 1003 VCL_call {^RECV$} + expect * 1003 ReqHeader {^Content-Length: 20$} + expect * 1003 VCL_call {^RECV$} expect 0 1003 VCL_return {^pass$} expect 0 1003 RespProtocol {^HTTP/1.1$} expect 0 1003 RespStatus {^100$} @@ -70,9 +69,8 @@ logexpect l1 -v v1 -g raw { expect 0 1005 ReqMethod {^POST$} expect 0 1005 ReqURL {^/$} expect 0 1005 ReqProtocol {^HTTP/1.1$} - expect 0 1005 ReqHeader {^Content-Length: 3$} - expect 0 1005 ReqHeader {^X-Forwarded-For:} - expect 0 1005 VCL_call {^RECV$} + expect * 1005 ReqHeader {^Content-Length: 3$} + expect * 1005 VCL_call {^RECV$} expect 0 1005 VCL_return {^pass$} expect 0 1005 VCL_call {^HASH$} @@ -82,9 +80,8 @@ logexpect l1 -v v1 -g raw { expect 0 1007 ReqMethod {^POST$} expect 0 1007 ReqURL {^/late$} expect 0 1007 ReqProtocol {^HTTP/1.1$} - expect 0 1007 ReqHeader {^Content-Length: 20$} - expect 0 1007 ReqHeader {^X-Forwarded-For:} - expect 0 1007 VCL_call {^RECV$} + expect * 1007 ReqHeader {^Content-Length: 20$} + expect * 1007 VCL_call {^RECV$} expect 0 1007 VCL_return {^pass$} expect 0 1007 VCL_call {^HASH$} expect 0 1007 VCL_return {^lookup$} @@ -104,9 +101,8 @@ logexpect l1 -v v1 -g raw { expect 0 1009 ReqMethod {^POST$} expect 0 1009 ReqURL {^/latecache$} expect 0 1009 ReqProtocol {^HTTP/1.1$} - expect 0 1009 ReqHeader {^Content-Length: 20$} - expect 0 1009 ReqHeader {^X-Forwarded-For:} - expect 0 1009 VCL_call {^RECV$} + expect * 1009 ReqHeader {^Content-Length: 20$} + expect * 1009 VCL_call {^RECV$} expect 0 1009 Storage {^(malloc|umem) Transient$} expect 0 1009 RespProtocol {^HTTP/1.1$} expect 0 1009 RespStatus {^100$} @@ -121,9 +117,8 @@ logexpect l1 -v v1 -g raw { expect 0 1011 ReqMethod {^POST$} expect 0 1011 ReqURL {^/err$} expect 0 1011 ReqProtocol {^HTTP/1.1$} - expect 0 1011 ReqHeader {^Content-Length: 20$} - expect 0 1011 ReqHeader {^X-Forwarded-For:} - expect 0 1011 VCL_call {^RECV$} + expect * 1011 ReqHeader {^Content-Length: 20$} + expect * 1011 VCL_call {^RECV$} expect 0 1011 VCL_return {^synth$} expect 0 1011 VCL_call {^HASH$} expect 0 1011 VCL_return {^lookup$} diff --git a/bin/varnishtest/tests/c00039.vtc b/bin/varnishtest/tests/c00039.vtc index 370234fdf..4c36c2ac2 100644 --- a/bin/varnishtest/tests/c00039.vtc +++ b/bin/varnishtest/tests/c00039.vtc @@ -40,7 +40,7 @@ client c1 { client c1 { # Each line is 32 bytes. Total: 32 * 8 == 256 - send "GET /....0....5....0. HTTP/1.1\r\n" + send "GET /..... HTTP/1.1\r\nHost: foo\r\n" send "1...5: ..0....5....0....5....0\r\n" send "1...5: ..0....5....0....5....0\r\n" send "1...5: ..0....5....0....5....0\r\n" @@ -52,8 +52,7 @@ client c1 { expect resp.status == 200 # Each line is 32 except last, which is 33. Total: 32 * 7 + 33 == 257 - send "GET /....0....5....0. HTTP/1.1\r\n" - send "1...5: ..0....5....0....5....0\r\n" + send "GET /..... HTTP/1.1\r\nHost: foo\r\n" send "1...5: ..0....5....0....5....0\r\n" send "1...5: ..0....5....0....5....0\r\n" send "1...5: ..0....5....0....5....0\r\n" diff --git a/bin/varnishtest/tests/e00003.vtc b/bin/varnishtest/tests/e00003.vtc index 71c5c6308..a541596bf 100644 --- a/bin/varnishtest/tests/e00003.vtc +++ b/bin/varnishtest/tests/e00003.vtc @@ -33,7 +33,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" # ReqAcct body counts include chunked overhead - expect * = ReqAcct "^18 0 18 187 104 291$" + expect * = ReqAcct "^29 0 29 187 104 291$" expect 0 = End } -start @@ -57,19 +57,19 @@ logexpect l5 -v v1 -g request { expect * 1005 Begin "^req .* rxreq" # ReqAcct body counts include chunked overhead # Header bytes is 5 larger than in l1 due to two item X-Varnish hdr - expect * = ReqAcct "^18 0 18 192 104 296$" + expect * = ReqAcct "^29 0 29 192 104 296$" expect 0 = End } -start client c1 { - txreq + txreq -hdr "Host: foo" rxresp expect resp.bodylen == 75 expect resp.status == 200 delay .1 # test that there is no difference on miss/hit - txreq + txreq -hdr "Host: foo" rxresp expect resp.bodylen == 75 expect resp.status == 200 diff --git a/bin/varnishtest/tests/f00001.vtc b/bin/varnishtest/tests/f00001.vtc index dc9fd9b19..2c756c9cd 100644 --- a/bin/varnishtest/tests/f00001.vtc +++ b/bin/varnishtest/tests/f00001.vtc @@ -12,6 +12,7 @@ varnish v1 -vcl+backend { client c1 { send "POST / HTTP/1.1\r\n" + send "Host: foo\r\n" send "Transfer-Encoding: chunked\r\n\r\n" send "FFFFFFFFFFFFFFED\r\n" send "0\r\n\r\n" @@ -32,6 +33,7 @@ varnish v1 -vcl+backend { client c1 { send "POST / HTTP/1.1\r\n" + send "Host: foo\r\n" send "Transfer-Encoding: chunked\r\n\r\n" send "FFFFFFFFFFFFFFED\r\n" diff --git a/bin/varnishtest/tests/l00002.vtc b/bin/varnishtest/tests/l00002.vtc index 942c8b5d9..82296bc66 100644 --- a/bin/varnishtest/tests/l00002.vtc +++ b/bin/varnishtest/tests/l00002.vtc @@ -24,9 +24,10 @@ varnish v1 -vcl+backend { # Request (1001): # GET /1 HTTP/1.1\r\n 17 bytes +# Host: foo\r\n 11 bytes # Content-Length: 4\r\n 19 bytes # \r\n 2 bytes -# Total: 38 bytes +# Total: 49 bytes # Response: # HTTP/1.1 200 OK\r\n 17 bytes # Content-Length: 1000\r\n 22 bytes @@ -37,8 +38,9 @@ varnish v1 -vcl+backend { # Request (1003): # GET /2 HTTP/1.1\r\n 17 bytes +# Host: foo\r\n 11 bytes # \r\n 2 bytes -# Total: 19 bytes +# Total: 30 bytes # Response: # HTTP/1.1 200 OK\r\n 17 bytes # Content-Length: 2000\r\n 22 bytes @@ -49,8 +51,9 @@ varnish v1 -vcl+backend { # Request (1005): # GET /2 HTTP/1.1\r\n 17 bytes +# Host: foo\r\n 11 bytes # \r\n 2 bytes -# Total: 19 bytes +# Total: 30 bytes # Response: # HTTP/1.1 200 OK\r\n 17 bytes # Content-Length: 2000\r\n 22 bytes @@ -69,13 +72,13 @@ varnish v1 -vcl+backend { # Total: 28 bytes logexpect l1 -v v1 -g session { expect * 1001 Begin "^req .* rxreq" - expect * = ReqAcct "^38 4 42 87 1000 1087$" + expect * = ReqAcct "^49 4 53 87 1000 1087$" expect 0 = End expect * 1003 Begin "^req .* rxreq" - expect * = ReqAcct "^19 0 19 87 2000 2087$" + expect * = ReqAcct "^30 0 30 87 2000 2087$" expect 0 = End expect * 1005 Begin "^req .* rxreq" - expect * = ReqAcct "^19 0 19 87 2000 2087$" + expect * = ReqAcct "^30 0 30 87 2000 2087$" expect 0 = End expect * 1006 Begin "^req .* rxreq" expect * = ReqAcct "^7 0 7 28 0 28$" @@ -84,11 +87,11 @@ logexpect l1 -v v1 -g session { # Request 1001 client c1 { - txreq -url "/1" -body "asdf" + txreq -url "/1" -hdr "Host: foo" -body "asdf" rxresp expect resp.status == 200 - send "GET /2 HTTP/1.1\r\n\r\nGET /2 HTTP/1.1\r\n\r\n" + send "GET /2 HTTP/1.1\r\nHost: foo\r\n\r\nGET /2 HTTP/1.1\r\nHost: foo\r\n\r\n" rxresp expect resp.status == 200 rxresp @@ -101,7 +104,7 @@ client c1 { logexpect l1 -wait -varnish v1 -expect s_req_hdrbytes == 83 +varnish v1 -expect s_req_hdrbytes == 116 varnish v1 -expect s_req_bodybytes == 4 varnish v1 -expect s_resp_hdrbytes == 289 varnish v1 -expect s_resp_bodybytes == 5000 diff --git a/bin/varnishtest/tests/l00003.vtc b/bin/varnishtest/tests/l00003.vtc index 6ef90a3db..bdc23333c 100644 --- a/bin/varnishtest/tests/l00003.vtc +++ b/bin/varnishtest/tests/l00003.vtc @@ -30,8 +30,9 @@ varnish v1 -vcl+backend { # Request (1001): # GET / HTTP/1.1\r\n 16 bytes +# Host: foo\r\n 11 bytes # \r\n 2 bytes -# Total: 18 bytes +# Total: 29 bytes # Reponse: # HTTP/1.1 200 OK\r\n 17 bytes @@ -62,7 +63,7 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" - expect * = ReqAcct "^18 0 18 93 55 148$" + expect * = ReqAcct "^29 0 29 93 55 148$" expect 0 = End expect * 1003 Begin "^req .* esi" expect * = ReqAcct "^0 0 0 0 12 12$" @@ -76,7 +77,7 @@ logexpect l1 -v v1 -g request { } -start client c1 { - txreq -url "/" + txreq -url "/" -hdr "Host: foo" rxresp expect resp.status == 200 expect resp.body == "123abc123defghi" @@ -84,7 +85,7 @@ client c1 { logexpect l1 -wait -varnish v1 -expect s_req_hdrbytes == 18 +varnish v1 -expect s_req_hdrbytes == 29 varnish v1 -expect s_req_bodybytes == 0 varnish v1 -expect s_resp_hdrbytes == 93 varnish v1 -expect s_resp_bodybytes == 55 diff --git a/bin/varnishtest/tests/l00004.vtc b/bin/varnishtest/tests/l00004.vtc index 22e5ea33b..95ad36111 100644 --- a/bin/varnishtest/tests/l00004.vtc +++ b/bin/varnishtest/tests/l00004.vtc @@ -22,9 +22,10 @@ varnish v1 -vcl+backend { # req: # POST / HTTP/1.1\r\n 17 bytes +# Host: foo\r\n 11 bytes # Content-Length: 4\r\n 19 bytes # \r\n 2 bytes -# Total: 38 bytes +# Total: 49 bytes # bereq: # POST / HTTP/1.1\r\n 17 bytes @@ -45,12 +46,12 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g request { expect 0 1001 Begin "^req .* rxreq" - expect * = PipeAcct "^38 49 4 42$" + expect * = PipeAcct "^49 60 4 42$" expect 0 = End } -start client c1 { - txreq -req "POST" -url "/" -hdr "Content-Length: 4" + txreq -req "POST" -url "/" -hdr "Content-Length: 4" -hdr "Host: foo" send "asdf" rxresp expect resp.status == 200 @@ -58,6 +59,6 @@ client c1 { logexpect l1 -wait -varnish v1 -expect s_pipe_hdrbytes == 38 +varnish v1 -expect s_pipe_hdrbytes == 49 varnish v1 -expect s_pipe_in == 4 varnish v1 -expect s_pipe_out == 42 diff --git a/bin/varnishtest/tests/o00000.vtc b/bin/varnishtest/tests/o00000.vtc index 3bb7cd511..1e5dcabf8 100644 --- a/bin/varnishtest/tests/o00000.vtc +++ b/bin/varnishtest/tests/o00000.vtc @@ -199,7 +199,7 @@ delay .1 # Try with appended request (See also: #1728) client c2 { - send "PROXY TCP6 1:f::3 5:a::8 1234 5678\r\nGET /3 HTTP/1.1\r\nHdr1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n\r\n" + send "PROXY TCP6 1:f::3 5:a::8 1234 5678\r\nGET /3 HTTP/1.1\r\nHost: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n\r\n" rxresp expect resp.http.url == "/3" } -run diff --git a/bin/varnishtest/tests/o00001.vtc b/bin/varnishtest/tests/o00001.vtc index ae6e388e0..ef78b2d95 100644 --- a/bin/varnishtest/tests/o00001.vtc +++ b/bin/varnishtest/tests/o00001.vtc @@ -1,17 +1,40 @@ varnishtest "PROXY v2 test" server s1 { - # The server address is part of the hash-key - # so we need three responses rxreq + expect req.url == "/1" expect req.http.x-forwarded-for == "${localhost}" - txresp -hdr "Obj: 1" + txresp + + rxreq + expect req.url == "/2" + expect req.http.x-forwarded-for == "${localhost}" + txresp + rxreq + expect req.url == "/3" + expect req.http.x-forwarded-for == "${localhost}" + txresp + + rxreq + expect req.url == "/4" + expect req.http.x-forwarded-for == "${localhost}" + txresp + + rxreq + expect req.url == "/5" + expect req.http.x-forwarded-for == "${localhost}" + txresp + + rxreq + expect req.url == "/6" expect req.http.x-forwarded-for == "1.2.3.4" - txresp -hdr "Obj: 2" + txresp + rxreq + expect req.url == "/7" expect req.http.x-forwarded-for == "102:304:506::d0e:f10" - txresp -hdr "Obj: 3" + txresp } -start varnish v1 -proto "PROXY" -vcl+backend { @@ -21,6 +44,7 @@ varnish v1 -proto "PROXY" -vcl+backend { "1.2.3.4"; "102:304:506::d0e:f10"; } + acl fwd_server { "5.6.7.8"; "8182:8384:8586::8d8e:8f80"; @@ -44,18 +68,18 @@ logexpect l1 -v v1 -g raw { expect * 1000 Proxy "2 local local local local" expect * 1003 ProxyGarbage "PROXY2: bad command \\(2\\)" expect * 1004 ProxyGarbage "PROXY2: Ignoring UNSPEC\\|UNSPEC addresses" - expect * 1006 ProxyGarbage "PROXY2: Ignoring unsupported protocol \\(0x99\\)" - expect * 1008 ProxyGarbage "PROXY2: Ignoring short IPv4 addresses \\(11\\)" - expect * 1010 ProxyGarbage "PROXY2: Ignoring short IPv6 addresses \\(35\\)" - expect * 1012 Proxy "2 1.2.3.4 2314 5.6.7.8 2828" - expect * 1015 Proxy "2 102:304:506::d0e:f10 2314 8182:8384:8586::8d8e:8f80 2828" + expect * 1007 ProxyGarbage "PROXY2: Ignoring unsupported protocol \\(0x99\\)" + expect * 1010 ProxyGarbage "PROXY2: Ignoring short IPv4 addresses \\(11\\)" + expect * 1013 ProxyGarbage "PROXY2: Ignoring short IPv6 addresses \\(35\\)" + expect * 1016 Proxy "2 1.2.3.4 2314 5.6.7.8 2828" + expect * 1019 Proxy "2 102:304:506::d0e:f10 2314 8182:8384:8586::8d8e:8f80 2828" } -start client c1 { # LOCAL command sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" sendhex "20 00 00 00" - txreq + txreq -url /1 rxresp expect resp.status == 200 expect resp.http.si == "${v1_addr}" @@ -79,7 +103,7 @@ client c1 { # UNSPEC proto sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" sendhex "21 00 00 00" - txreq + txreq -url /2 rxresp expect resp.status == 200 expect resp.http.si == "${v1_addr}" @@ -93,7 +117,7 @@ client c1 { # unknown proto sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" sendhex "21 99 00 00" - txreq + txreq -url /3 rxresp expect resp.status == 200 expect resp.http.si == "${v1_addr}" @@ -108,7 +132,7 @@ client c1 { sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" sendhex "21 11 00 0b" sendhex "01 02 03 04 05 06 07 08 09 0a 0b" - txreq + txreq -url /4 rxresp expect resp.status == 200 expect resp.http.si == "${v1_addr}" @@ -125,7 +149,7 @@ client c1 { sendhex "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" sendhex "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" sendhex "01 02 03" - txreq + txreq -url /5 rxresp expect resp.status == 200 expect resp.http.fs == false @@ -138,10 +162,9 @@ delay .1 # good IPv4 client c1 -proxy2 "1.2.3.4:2314 5.6.7.8:2828" { - txreq + txreq -url /6 rxresp expect resp.status == 200 - expect resp.http.obj == 2 expect resp.http.fs == true expect resp.http.fc == true expect resp.http.ci == "1.2.3.4" @@ -158,10 +181,9 @@ delay .1 # good IPv6 client c1 \ -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828" { - txreq + txreq -url /7 rxresp expect resp.status == 200 - expect resp.http.obj == 3 expect resp.http.fs == true expect resp.http.fc == true expect resp.http.ci == "102:304:506::d0e:f10" diff --git a/bin/varnishtest/tests/r00262.vtc b/bin/varnishtest/tests/r00262.vtc index b5a9efc8e..698a0b068 100644 --- a/bin/varnishtest/tests/r00262.vtc +++ b/bin/varnishtest/tests/r00262.vtc @@ -10,13 +10,13 @@ server s1 { varnish v1 -arg "-p timeout_linger=20" -vcl+backend { } -start client c1 { - send "GET / HTTP/1.1\r\n\r\n\r\n" + send "GET / HTTP/1.1\r\nHost: foo\r\n\r\n\r\n" rxresp expect resp.status == 200 expect resp.http.X-Varnish == "1001" - send "GET / HTTP/1.1\r\n\r\n" + send "GET / HTTP/1.1\r\nHost: foo\r\n\r\n" rxresp expect resp.status == 200 expect resp.http.X-Varnish == "1003 1002" diff --git a/bin/varnishtest/tests/r01729.vtc b/bin/varnishtest/tests/r01729.vtc index 1a68f5bbc..883a60cc6 100644 --- a/bin/varnishtest/tests/r01729.vtc +++ b/bin/varnishtest/tests/r01729.vtc @@ -23,6 +23,7 @@ client c1 { non_fatal send "PUT /1 HTTP/1.1\r\n" + send "Host: foo\r\n" send "Content-Length: 31\r\n" send "Transfer-Encoding: chunked\r\n" send "\r\n" @@ -39,6 +40,7 @@ client c1 { client c1 { fatal send "PUT /2 HTTP/1.1\r\n" + send "Host: foo\r\n" send "Transfer-Encoding: chunked\r\n" send "\r\n" send "14\r\n" diff --git a/bin/varnishtest/tests/r01847.vtc b/bin/varnishtest/tests/r01847.vtc index a163fe3b7..ac764ee89 100644 --- a/bin/varnishtest/tests/r01847.vtc +++ b/bin/varnishtest/tests/r01847.vtc @@ -24,9 +24,9 @@ client c1 { expect resp.http.rxhost == www.example.com expect resp.http.rxurl == /bar - txreq -url https://www.example.com/bar + txreq -url https://www.example.com/bar -hdr "Host: ${localhost}" rxresp - expect resp.http.rxhost == "" + expect resp.http.rxhost == "${localhost}" expect resp.http.rxurl == https://www.example.com/bar } -run diff --git a/bin/varnishtest/tests/u00003.vtc b/bin/varnishtest/tests/u00003.vtc index f73530df5..197e5a89d 100644 --- a/bin/varnishtest/tests/u00003.vtc +++ b/bin/varnishtest/tests/u00003.vtc @@ -32,9 +32,9 @@ shell { delay 1 client c1 { - txreq -url /1?foo=bar -hdr "authorization: basic dXNlcjpwYXNz" + txreq -url /1?foo=bar -hdr "authorization: basic dXNlcjpwYXNz" -hdr "Host: ${localhost}" rxresp - txreq -url /1?foo=bar -hdr "baz: qux" + txreq -url /1?foo=bar -hdr "baz: qux" -hdr "Host: ${localhost}" rxresp } -run @@ -44,7 +44,7 @@ shell "mv ${tmpdir}/ncsa.log ${tmpdir}/ncsa.old.log" shell "kill -HUP `cat ${tmpdir}/ncsa.pid`" client c1 { - txreq -url /2 + txreq -url /2 -hdr "Host: ${localhost}" rxresp } -run @@ -53,10 +53,10 @@ delay 1 shell "kill `cat ${tmpdir}/ncsa.pid`" # default formatter and rotation -shell -match {^\d+.\d+.\d+.\d+ - user \[../.../20[1-9][0-9]:..:..:.. (?# -)[+-]....\] "GET http://localhost/1\?foo=bar HTTP/1.1" 200 100 "-" "-" -\d+.\d+.\d+.\d+ - - \[../.../20[1-9][0-9]:..:..:.. [+-]....\] (?# -)"GET http://localhost/1\?foo=bar HTTP/1.1" 404 \d+ "-" "-"$} \ +shell -match {${localhost} - user \[../.../20[1-9][0-9]:..:..:.. (?# +)[+-]....\] "GET http://${localhost}/1\?foo=bar HTTP/1.1" 200 100 "-" "-" +${localhost} - - \[../.../20[1-9][0-9]:..:..:.. [+-]....\] (?# +)"GET http://${localhost}/1\?foo=bar HTTP/1.1" 404 \d+ "-" "-"$} \ "cat ${tmpdir}/ncsa.old.log" shell "grep -q /2 ${tmpdir}/ncsa.log" @@ -111,13 +111,13 @@ shell -err -match "Usage: .*varnishncsa " \ {varnishncsa extra} # -b -shell -match {^\d+.\d+.\d+.\d+ 100 -- 0$} \ +shell -match {^${localhost} 100 +${localhost} 0$} \ {varnishncsa -n ${v1_name} -b -d -F "%{Host}i %b"} # -c -shell -match {^- 100 -- \d+ -- -$} \ +shell -match {^${localhost} 100 +${localhost} \d+ +${localhost} -$} \ {varnishncsa -n ${v1_name} -c -d -F "%{Host}i %b"} # -f and standard formatters diff --git a/bin/varnishtest/tests/u00013.vtc b/bin/varnishtest/tests/u00013.vtc index 411bba8f3..133d9992a 100644 --- a/bin/varnishtest/tests/u00013.vtc +++ b/bin/varnishtest/tests/u00013.vtc @@ -3,8 +3,8 @@ varnishtest "varnishncsa outputs when UDS addresses are in use" # The %h formatter gets its value from ReqStart or BackendStart, # which now may be a UDS address. -# For UDS backends without a .hosthdr setting, the Host header is -# set to "0.0.0.0", which may appear in %r output. +# For UDS backends without a .host_header spec, the Host header is +# set to "0.0.0.0" if the header is missing in the request. server s1 -listen "${tmpdir}/s1.sock" { rxreq @@ -14,7 +14,7 @@ server s1 -listen "${tmpdir}/s1.sock" { varnish v1 -arg "-a ${tmpdir}/v1.sock" -vcl+backend {} -start client c1 -connect "${tmpdir}/v1.sock" { - txreq + txreq -proto HTTP/1.0 rxresp } -run diff --git a/bin/varnishtest/tests/v00008.vtc b/bin/varnishtest/tests/v00008.vtc index 95a870ff2..42798f2b3 100644 --- a/bin/varnishtest/tests/v00008.vtc +++ b/bin/varnishtest/tests/v00008.vtc @@ -17,7 +17,7 @@ varnish v1 -vcl+backend { } -start client c1 { txreq -url "/foo" -hdr "Host: snafu" rxresp - txreq -url "/bar" + txreq -url "/bar" -proto HTTP/1.0 rxresp } -run @@ -37,6 +37,6 @@ varnish v1 -vcl { } client c1 { - txreq -url "/barf" + txreq -url "/barf" -proto HTTP/1.0 rxresp } -run diff --git a/bin/varnishtest/tests/v00057.vtc b/bin/varnishtest/tests/v00057.vtc index 58d8de3c6..01a177b1e 100644 --- a/bin/varnishtest/tests/v00057.vtc +++ b/bin/varnishtest/tests/v00057.vtc @@ -1,4 +1,4 @@ -varnishtest "Test backend .hosthdr with UDS backends" +varnishtest "Test host header specification with UDS backends" server s1 -listen "${tmpdir}/s1.sock" { rxreq @@ -17,7 +17,7 @@ varnish v1 -vcl+backend { } -start client c1 { txreq -url "/foo" -hdr "Host: snafu" rxresp - txreq -url "/bar" + txreq -url "/bar" -proto HTTP/1.0 rxresp } -run @@ -36,6 +36,6 @@ varnish v1 -vcl { } client c1 { - txreq -url "/barf" + txreq -url "/barf" -proto HTTP/1.0 rxresp } -run From fgsch at lodoss.net Thu Aug 16 08:52:27 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:27 +0000 (UTC) Subject: [6.0] c65bf8e33 Include the Host header if not present Message-ID: <20180816085227.706E19877D@lists.varnish-cache.org> commit c65bf8e335e30a6e2dd5d720c62c0d457ebbe634 Author: Federico G. Schwindt Date: Thu Mar 29 00:09:16 2018 -0300 Include the Host header if not present Enforced for HTTP/1.1 requests. To disable it use -nohost. diff --git a/bin/varnishtest/tests/r01847.vtc b/bin/varnishtest/tests/r01847.vtc index ac764ee89..8249cd2df 100644 --- a/bin/varnishtest/tests/r01847.vtc +++ b/bin/varnishtest/tests/r01847.vtc @@ -24,7 +24,7 @@ client c1 { expect resp.http.rxhost == www.example.com expect resp.http.rxurl == /bar - txreq -url https://www.example.com/bar -hdr "Host: ${localhost}" + txreq -url https://www.example.com/bar rxresp expect resp.http.rxhost == "${localhost}" expect resp.http.rxurl == https://www.example.com/bar diff --git a/bin/varnishtest/tests/u00003.vtc b/bin/varnishtest/tests/u00003.vtc index 197e5a89d..e18d9b912 100644 --- a/bin/varnishtest/tests/u00003.vtc +++ b/bin/varnishtest/tests/u00003.vtc @@ -32,9 +32,9 @@ shell { delay 1 client c1 { - txreq -url /1?foo=bar -hdr "authorization: basic dXNlcjpwYXNz" -hdr "Host: ${localhost}" + txreq -url /1?foo=bar -hdr "authorization: basic dXNlcjpwYXNz" rxresp - txreq -url /1?foo=bar -hdr "baz: qux" -hdr "Host: ${localhost}" + txreq -url /1?foo=bar -hdr "baz: qux" rxresp } -run @@ -44,7 +44,7 @@ shell "mv ${tmpdir}/ncsa.log ${tmpdir}/ncsa.old.log" shell "kill -HUP `cat ${tmpdir}/ncsa.pid`" client c1 { - txreq -url /2 -hdr "Host: ${localhost}" + txreq -url /2 rxresp } -run diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 1f724924a..ab0ff6ec3 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -172,7 +172,7 @@ macro_undef(struct vtclog *vl, const char *instance, const char *name) AZ(pthread_mutex_unlock(¯o_mtx)); } -static char * +char * macro_get(const char *b, const char *e) { struct macro *m; diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 8878e1d37..f5b8e350c 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -114,6 +114,7 @@ void macro_undef(struct vtclog *vl, const char *instance, const char *name); void macro_def(struct vtclog *vl, const char *instance, const char *name, const char *fmt, ...) v_printflike_(4, 5); +char *macro_get(const char *, const char *); struct vsb *macro_expand(struct vtclog *vl, const char *text); struct vsb *macro_expandf(struct vtclog *vl, const char *, ...) v_printflike_(2, 3); diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index e5857e7eb..0634d6669 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -832,11 +832,12 @@ gzip_body(const struct http *hp, const char *txt, char **body, int *bodylen) static char* const * http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, - char* body) + char *body, unsigned nohost) { int bodylen = 0; char *b, *c; char *nullbody; + char *m; int nolen = 0; int l; @@ -846,7 +847,11 @@ http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, for (; *av != NULL; av++) { if (!strcmp(*av, "-nolen")) { nolen = 1; + } else if (!strcmp(*av, "-nohost")) { + nohost = 1; } else if (!strcmp(*av, "-hdr")) { + if (!strncasecmp(av[1], "Host:", 5)) + nohost = 1; VSB_printf(hp->vsb, "%s%s", av[1], nl); av++; } else if (!strcmp(*av, "-hdrlen")) { @@ -904,6 +909,12 @@ http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, } else break; } + if (!nohost) { + m = macro_get("localhost", NULL); + AN(m); + VSB_printf(hp->vsb, "Host: %s%s", m, nl); + free(m); + } if (body != NULL && !nolen) VSB_printf(hp->vsb, "Content-Length: %d%s", bodylen, nl); VSB_cat(hp->vsb, nl); @@ -944,8 +955,11 @@ http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, * These three switches can appear in any order but must come before the * following ones. * + * \-nohost + * Don't include a Host header in the request. + * * \-nolen - * Don't include a Content-Length header in the response. + * Don't include a Content-Length header. * * \-hdr STRING * Add STRING as a header, it must follow this format: @@ -1019,7 +1033,7 @@ cmd_http_txresp(CMD_ARGS) /* send a "Content-Length: 0" header unless something else happens */ REPLACE(body, ""); - av = http_tx_parse_args(av, vl, hp, body); + av = http_tx_parse_args(av, vl, hp, body, 1); if (*av != NULL) vtc_fatal(hp->vl, "Unknown http txresp spec: %s\n", *av); @@ -1207,6 +1221,7 @@ cmd_http_txreq(CMD_ARGS) const char *url = "/"; const char *proto = "HTTP/1.1"; const char *up = NULL; + unsigned nohost; (void)cmd; (void)vl; @@ -1240,7 +1255,8 @@ cmd_http_txreq(CMD_ARGS) "Upgrade: h2c%s" "HTTP2-Settings: %s%s", nl, nl, up, nl); - av = http_tx_parse_args(av, vl, hp, NULL); + nohost = strcasecmp(proto, "HTTP/1.1") != 0; + av = http_tx_parse_args(av, vl, hp, NULL, nohost); if (*av != NULL) vtc_fatal(hp->vl, "Unknown http txreq spec: %s\n", *av); http_write(hp, 4, "txreq"); From phk at FreeBSD.org Thu Aug 16 08:52:27 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:27 +0000 (UTC) Subject: [6.0] 96ba7a4a2 Add function to produce HAproxy backend confs Message-ID: <20180816085227.BF5D9987A8@lists.varnish-cache.org> commit 96ba7a4a20cbeb468d32a17958bc127bf45272d8 Author: Poul-Henning Kamp Date: Thu Mar 29 11:05:02 2018 +0000 Add function to produce HAproxy backend confs diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index f5b8e350c..5776e9b03 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -91,7 +91,8 @@ int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, char * synth_body(const char *len, int rnd); -void cmd_server_genvcl(struct vsb *vsb); +void cmd_server_gen_vcl(struct vsb *vsb); +void cmd_server_gen_haproxy_conf(struct vsb *vsb); void vtc_loginit(char *buf, unsigned buflen); struct vtclog *vtc_logopen(const char *id); diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 949604634..a339a7f5f 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -386,7 +386,7 @@ server_wait(struct server *s) */ void -cmd_server_genvcl(struct vsb *vsb) +cmd_server_gen_vcl(struct vsb *vsb) { struct server *s; @@ -406,6 +406,39 @@ cmd_server_genvcl(struct vsb *vsb) } +/********************************************************************** + * Generate VCL backend decls for our servers + */ + +void +cmd_server_gen_haproxy_conf(struct vsb *vsb) +{ + struct server *s; + + AZ(pthread_mutex_lock(&server_mtx)); + VTAILQ_FOREACH(s, &servers, list) { + if (*s->listen != '/') + VSB_printf(vsb, + "\n backend be%s\n" + "\tserver srv%s %s:%s\n", + s->name + 1, s->name + 1, s->aaddr, s->aport); + else + INCOMPL(); + } + VTAILQ_FOREACH(s, &servers, list) { + if (*s->listen != '/') + VSB_printf(vsb, + "\n frontend http%s\n" + "\tuse_backend be%s\n" + "\tbind \"fd@${fe%s}\"\n", + s->name + 1, s->name + 1, s->name + 1); + else + INCOMPL(); + } + AZ(pthread_mutex_unlock(&server_mtx)); +} + + /********************************************************************** * Server command dispatch */ diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index d09d7cf45..4c2e52999 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -754,7 +754,7 @@ varnish_vclbackend(struct varnish *v, const char *vcl) VSB_printf(vsb2, "vcl %.1f;\n", v->syntax); - cmd_server_genvcl(vsb2); + cmd_server_gen_vcl(vsb2); AZ(VSB_finish(vsb2)); From phk at FreeBSD.org Thu Aug 16 08:52:27 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:27 +0000 (UTC) Subject: [6.0] 820e38de5 Move -f argument later in argv Message-ID: <20180816085228.1F0C5987BD@lists.varnish-cache.org> commit 820e38de58b46e3be8d2d02fee60a51a85b3ca33 Author: Poul-Henning Kamp Date: Thu Mar 29 11:05:28 2018 +0000 Move -f argument later in argv Add -conf+backend to automatically produce backend confs from list of servers diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index e3ea8d22d..0cb2dad7d 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -200,8 +200,6 @@ haproxy_new(const char *name) h->cfg_fn = strdup(buf); AN(h->cfg_fn); - VSB_printf(h->args, "-f %s ", h->cfg_fn); - bprintf(buf, "rm -rf %s ; mkdir -p %s", h->workdir, h->workdir); AZ(system(buf)); @@ -285,6 +283,8 @@ haproxy_start(struct haproxy *h) AN(vsb); VSB_printf(vsb, "exec %s %s", h->filename, VSB_data(h->args)); + VSB_printf(vsb, " -f %s ", h->cfg_fn); + if (h->opt_worker || h->opt_daemon) { bprintf(buf, "%s/pid", h->workdir); h->pid_fn = strdup(buf); @@ -459,7 +459,7 @@ haproxy_build_backends(const struct haproxy *h, const char *vsb_data) */ static void -haproxy_write_conf(const struct haproxy *h, const char *cfg) +haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) { struct vsb *vsb, *vsb2; @@ -472,6 +472,10 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg) VSB_printf(vsb, " global\n\tstats socket %s " "level admin mode 600\n", h->cli_fn); AZ(VSB_cat(vsb, cfg)); + + if (auto_be) + cmd_server_gen_haproxy_conf(vsb); + AZ(VSB_finish(vsb)); AZ(haproxy_build_backends(h, VSB_data(vsb))); @@ -494,7 +498,7 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg) * * To define a haproxy server, you'll use this syntax:: * - * haproxy hNAME [-arg STRING] [-conf STRING] + * haproxy hNAME [-arg STRING] [-conf[+vcl] STRING] * * The first ``haproxy hNAME`` invocation will start the haproxy master * process in the background, waiting for the ``-start`` switch to actually @@ -511,6 +515,10 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg) * \-conf STRING * Specify the configuration to be loaded by this HAProxy instance. * + * \-conf+backend STRING + * Specify the configuration to be loaded by this HAProxy instance, + * all server instances will be automatically appended + * * You can decide to start the HAProxy instance and/or wait for several events:: * * haproxy hNAME [-start] [-wait-running] [-wait-stopped] @@ -587,7 +595,13 @@ cmd_haproxy(CMD_ARGS) } if (!strcmp(*av, "-conf")) { AN(av[1]); - haproxy_write_conf(h, av[1]); + haproxy_write_conf(h, av[1], 0); + av++; + continue; + } + if (!strcmp(*av, "-conf+backend")) { + AN(av[1]); + haproxy_write_conf(h, av[1], 1); av++; continue; } From phk at FreeBSD.org Thu Aug 16 08:52:28 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:28 +0000 (UTC) Subject: [6.0] 6643c5f41 Add test-case for -conf+backend Message-ID: <20180816085228.5F956987CC@lists.varnish-cache.org> commit 6643c5f41059613106a827eedcc5499cdbd6f99d Author: Poul-Henning Kamp Date: Thu Mar 29 11:06:26 2018 +0000 Add test-case for -conf+backend diff --git a/bin/varnishtest/tests/h00003.vtc b/bin/varnishtest/tests/h00003.vtc new file mode 100644 index 000000000..c894495b5 --- /dev/null +++ b/bin/varnishtest/tests/h00003.vtc @@ -0,0 +1,26 @@ +varnishtest "Test -conf+backend" + +feature ignore_unknown_macro + +feature cmd {haproxy --version 2>&1 | grep -q 'HA-Proxy version'} + +server s1 { + rxreq + txresp -body "s1 >>> Hello world!" +} -start + +haproxy h1 -arg "-d" -conf+backend { + defaults + mode http + timeout connect 5s + timeout server 30s + timeout client 30s + +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.body == "s1 >>> Hello world!" +} -run From phk at FreeBSD.org Thu Aug 16 08:52:28 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:28 +0000 (UTC) Subject: [6.0] 665794fa2 Give vtc_record() the ability to collect the bits in a VSB Message-ID: <20180816085228.A2B09987EA@lists.varnish-cache.org> commit 665794fa22c7648fd813fcff871b89ceb24feae5 Author: Poul-Henning Kamp Date: Thu Mar 29 13:05:16 2018 +0000 Give vtc_record() the ability to collect the bits in a VSB diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 5776e9b03..94dbf14ee 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -134,7 +134,7 @@ struct vsb *vtc_hex_to_bin(struct vtclog *vl, const char *arg); void vtc_expect(struct vtclog *, const char *, const char *, const char *, const char *, const char *); void vtc_wait4(struct vtclog *, long, int, int, int); -void *vtc_record(struct vtclog *, int); +void *vtc_record(struct vtclog *, int, struct vsb *); /* vtc_term.c */ struct term *Term_New(struct vtclog *, int, int); diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 0cb2dad7d..4094ec08d 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -243,7 +243,7 @@ haproxy_thread(void *priv) struct haproxy *h; CAST_OBJ_NOTNULL(h, priv, HAPROXY_MAGIC); - return (vtc_record(h->vl, h->fds[0])); + return (vtc_record(h->vl, h->fds[0], NULL)); } /********************************************************************** diff --git a/bin/varnishtest/vtc_subr.c b/bin/varnishtest/vtc_subr.c index e232f95de..b3584a964 100644 --- a/bin/varnishtest/vtc_subr.c +++ b/bin/varnishtest/vtc_subr.c @@ -187,7 +187,7 @@ vtc_wait4(struct vtclog *vl, long pid, } void * -vtc_record(struct vtclog *vl, int fd) +vtc_record(struct vtclog *vl, int fd, struct vsb *vsb) { char buf[65536]; struct pollfd fds[1]; @@ -204,6 +204,8 @@ vtc_record(struct vtclog *vl, int fd) if (fds->revents & POLLIN) { i = read(fd, buf, sizeof buf - 1); if (i > 0) { + if (vsb != NULL) + VSB_bcat(vsb, buf, i); buf[i] = '\0'; vtc_dump(vl, 3, "debug", buf, -2); } diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index 4c2e52999..a688b62a2 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -376,7 +376,7 @@ varnish_thread(void *priv) struct varnish *v; CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC); - return (vtc_record(v->vl, v->fds[0])); + return (vtc_record(v->vl, v->fds[0], NULL)); } /********************************************************************** From phk at FreeBSD.org Thu Aug 16 08:52:27 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:27 +0000 (UTC) Subject: [6.0] 3c4281b1e Flexelinting pointer constness Message-ID: <20180816085227.9ABF598795@lists.varnish-cache.org> commit 3c4281b1e9cbb82d546085d338075a1eb7f63bce Author: Poul-Henning Kamp Date: Thu Mar 29 11:03:55 2018 +0000 Flexelinting pointer constness diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index ab0ff6ec3..d4e45c777 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -460,7 +460,8 @@ exec_file(const char *fn, const char *script, const char *tmpdir, { FILE *f; struct vsb *vsb; - char *p; + const char *p; + char *q; (void)signal(SIGPIPE, SIG_IGN); @@ -475,10 +476,10 @@ exec_file(const char *fn, const char *script, const char *tmpdir, vsb = VSB_new_auto(); AN(vsb); if (*fn != '/') { - p = macro_get("pwd", NULL); - AN(p); - VSB_cat(vsb, p); - free(p); + q = macro_get("pwd", NULL); + AN(q); + VSB_cat(vsb, q); + free(q); } p = strrchr(fn, '/'); if (p != NULL) { From phk at FreeBSD.org Thu Aug 16 08:52:28 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:28 +0000 (UTC) Subject: [6.0] 2abd43100 Eliminate arguments inherited from vtc_varnish's two-process handling. Message-ID: <20180816085228.D15F4987F1@lists.varnish-cache.org> commit 2abd4310090304d79c9be0a5919c227071ba9809 Author: Poul-Henning Kamp Date: Thu Mar 29 13:06:38 2018 +0000 Eliminate arguments inherited from vtc_varnish's two-process handling. diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 4094ec08d..d9c03508d 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -588,11 +588,6 @@ cmd_haproxy(CMD_ARGS) av++; continue; } - if (!strcmp(*av, "-cleanup")) { - AZ(av[1]); - haproxy_cleanup(h, 0); - continue; - } if (!strcmp(*av, "-conf")) { AN(av[1]); haproxy_write_conf(h, av[1], 0); @@ -614,18 +609,10 @@ cmd_haproxy(CMD_ARGS) haproxy_start(h); continue; } - if (!strcmp(*av, "-stop")) { - haproxy_stop(h); - continue; - } - if (!strcmp(*av, "-wait-stopped")) { + if (!strcmp(*av, "-wait")) { wait_stopped(h); continue; } - if (!strcmp(*av, "-wait-running")) { - wait_running(h); - continue; - } vtc_fatal(h->vl, "Unknown haproxy argument: %s", *av); } } From phk at FreeBSD.org Thu Aug 16 08:52:29 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:29 +0000 (UTC) Subject: [6.0] 1c8fed623 More work on vtc_haproxy. Message-ID: <20180816085229.10C8D98800@lists.varnish-cache.org> commit 1c8fed623298ec14a3ef5f0cb33b89b6eedec9f7 Author: Poul-Henning Kamp Date: Thu Mar 29 13:52:35 2018 +0000 More work on vtc_haproxy. I hadn't realized how unsuitable vtc_varnish was to copy from, because of the dual process complications, this simplifiles things back again. Move -D and -W out of -arg, it makes no sense to have to pull them out of there again. Add -conf-OK and -conf-BAD arguments. diff --git a/bin/varnishtest/tests/h00001.vtc b/bin/varnishtest/tests/h00001.vtc index 3c599a520..1b86d81a0 100644 --- a/bin/varnishtest/tests/h00001.vtc +++ b/bin/varnishtest/tests/h00001.vtc @@ -9,7 +9,7 @@ server s1 { txresp -body "s1 >>> Hello world!" } -start -haproxy h1 -arg "-d" -conf { +haproxy h1 -conf { defaults mode http timeout connect 5s diff --git a/bin/varnishtest/tests/h00002.vtc b/bin/varnishtest/tests/h00002.vtc index 6e2af6651..935f2331a 100644 --- a/bin/varnishtest/tests/h00002.vtc +++ b/bin/varnishtest/tests/h00002.vtc @@ -9,7 +9,7 @@ server s1 { txresp -body "s1 >>> Hello world!" } -start -haproxy h1 -arg "-D" -conf { +haproxy h1 -D -conf { defaults mode http timeout connect 5s diff --git a/bin/varnishtest/tests/h00003.vtc b/bin/varnishtest/tests/h00003.vtc index c894495b5..404b1eecb 100644 --- a/bin/varnishtest/tests/h00003.vtc +++ b/bin/varnishtest/tests/h00003.vtc @@ -9,7 +9,7 @@ server s1 { txresp -body "s1 >>> Hello world!" } -start -haproxy h1 -arg "-d" -conf+backend { +haproxy h1 -conf+backend { defaults mode http timeout connect 5s diff --git a/bin/varnishtest/tests/h00004.vtc b/bin/varnishtest/tests/h00004.vtc new file mode 100644 index 000000000..122e0411d --- /dev/null +++ b/bin/varnishtest/tests/h00004.vtc @@ -0,0 +1,18 @@ +varnishtest "Test -conf+backend" + +feature ignore_unknown_macro + +feature cmd {haproxy --version 2>&1 | grep -q 'HA-Proxy version'} + +haproxy h1 -conf-OK { + defaults + mode http + timeout connect 5s + timeout server 30s + timeout client 30s + +} + +haproxy h2 -conf-BAD {unknown keyword 'FOOBAR' in 'global' section} { + FOOBAR +} diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index d9c03508d..f8eec1215 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -37,7 +37,6 @@ #include "vtc.h" -#include "vav.h" #include "vfil.h" #include "vpf.h" #include "vtcp.h" @@ -46,9 +45,9 @@ #define HAPROXY_PROGRAM_ENV_VAR "HAPROXY_PROGRAM" #define HAPROXY_OPT_WORKER "-W" #define HAPROXY_OPT_DAEMON "-D" -#define HAPROXY_OPT_CHECK_MODE "-c" #define HAPROXY_SIGNAL SIGINT #define HAPROXY_EXPECT_EXIT (128 + HAPROXY_SIGNAL) +#define HAPROXY_GOOD_CONF "Configuration file is valid" struct haproxy { unsigned magic; @@ -77,10 +76,9 @@ struct haproxy { const char *cli_fn; char *workdir; + struct vsb *msgs; }; -static void haproxy_cleanup(struct haproxy *h, int is_haproxy_listener); - static VTAILQ_HEAD(, haproxy) haproxies = VTAILQ_HEAD_INITIALIZER(haproxies); @@ -89,42 +87,14 @@ static VTAILQ_HEAD(, haproxy) haproxies = */ static void -wait_stopped(struct haproxy *h) -{ - vtc_log(h->vl, 3, "wait-stopped"); - while (1) { - if (h->kill_status >= 0 || h->kill_errno == ESRCH) - break; - - usleep(1000); - h->kill_status = kill(h->pid, 0); - h->kill_errno = errno; - } -} - -static void -wait_running(struct haproxy *h) +haproxy_wait_pidfile(struct haproxy *h) { char buf_err[1024] = {0}; int usleep_time = 1000; double t0; pid_t pid; - if (h->opt_check_mode) - return; - - if (h->pid_fn == NULL) { - /* - * If we use no pid-file, check that the process - * we started is still running. - */ - if (kill(h->pid, 0) < 0) - vtc_fatal(h->vl, "Process %ld not there: %s", - (long)h->pid, strerror(errno)); - return; - } - - vtc_log(h->vl, 3, "wait-running"); + vtc_log(h->vl, 3, "wait-pid-file"); for (t0 = VTIM_mono(); VTIM_mono() - t0 < 3;) { if (vtc_error) return; @@ -243,7 +213,7 @@ haproxy_thread(void *priv) struct haproxy *h; CAST_OBJ_NOTNULL(h, priv, HAPROXY_MAGIC); - return (vtc_record(h->vl, h->fds[0], NULL)); + return (vtc_record(h->vl, h->fds[0], h->msgs)); } /********************************************************************** @@ -253,35 +223,30 @@ haproxy_thread(void *priv) static void haproxy_start(struct haproxy *h) { - char **argv; - int i; char buf[PATH_MAX]; struct vsb *vsb; vtc_log(h->vl, 2, "%s", __func__); AZ(VSB_finish(h->args)); - argv = VAV_Parse(VSB_data(h->args), NULL, 0); - AN(argv); - if (argv[0] != NULL) - vtc_fatal(h->vl, "Could not parse argv-string: %s", argv[0]); - for (i = 1; argv[i] != NULL; i++) { - /* Check if HAPROXY_OPT_WORKER option was provided. */ - if (!strcmp(argv[i], HAPROXY_OPT_WORKER)) { - h->opt_worker = 1; - } else if (!strcmp(argv[i], HAPROXY_OPT_DAEMON)) { - h->opt_daemon = 1; - } else if (!strcmp(argv[i], HAPROXY_OPT_CHECK_MODE)) { - h->opt_check_mode = 1; - } - } - VAV_Free(argv); vtc_log(h->vl, 4, "opt_worker %d opt_daemon %d opt_check_mode %d", h->opt_worker, h->opt_daemon, h->opt_check_mode); vsb = VSB_new_auto(); AN(vsb); - VSB_printf(vsb, "exec %s %s", h->filename, VSB_data(h->args)); + + VSB_printf(vsb, "exec %s", h->filename); + if (h->opt_check_mode) + VSB_printf(vsb, " -c"); + else if (h->opt_daemon) + VSB_printf(vsb, " -D"); + else + VSB_printf(vsb, " -d"); + + if (h->opt_worker) + VSB_printf(vsb, " -W"); + + VSB_printf(vsb, " %s", VSB_data(h->args)); VSB_printf(vsb, " -f %s ", h->cfg_fn); @@ -301,11 +266,10 @@ haproxy_start(struct haproxy *h) * if signaled by signal. */ h->expect_exit = HAPROXY_EXPECT_EXIT; - } else { - h->expect_exit = 0; } AZ(pipe(&h->fds[0])); + vtc_log(h->vl, 4, "XXX %d @%d", h->fds[1], __LINE__); AZ(pipe(&h->fds[2])); h->pid = h->ppid = fork(); assert(h->pid >= 0); @@ -334,73 +298,44 @@ haproxy_start(struct haproxy *h) AZ(pthread_create(&h->tp, NULL, haproxy_thread, h)); - wait_running(h); + if (h->pid_fn != NULL) + haproxy_wait_pidfile(h); } -/********************************************************************** - * Stop a HAProxy - */ - -static void -haproxy_stop(struct haproxy *h) -{ - if (h->opt_check_mode) - return; - - if (h->pid < 0) - haproxy_start(h); - - vtc_log(h->vl, 2, "Stop"); - h->kill_status = kill(h->pid, HAPROXY_SIGNAL); - h->kill_errno = errno; - h->expect_signal = -HAPROXY_SIGNAL; - - wait_stopped(h); -} /********************************************************************** - * Cleanup + * Wait for a HAProxy instance. */ static void -haproxy_cleanup(struct haproxy *h, int is_haproxy_listener) +haproxy_wait(struct haproxy *h) { void *p; - vtc_log(h->vl, 2, "%s (%d)", __func__, is_haproxy_listener); - if (!is_haproxy_listener) { - /* Close the STDIN connection. */ - closefd(&h->fds[1]); - - /* Wait until STDOUT+STDERR closes */ - AZ(pthread_join(h->tp, &p)); - closefd(&h->fds[0]); - if (h->opt_daemon) - return; - } - - if (h->ppid == -1) - return; - - vtc_wait4(h->vl, h->ppid, h->expect_exit, h->expect_signal, 0); - h->ppid = -1; -} - -/********************************************************************** - * Wait for a HAProxy instance. - */ + vtc_log(h->vl, 2, "Wait"); -static void -haproxy_wait(struct haproxy *h) -{ if (h->pid < 0) - return; + haproxy_start(h); - vtc_log(h->vl, 2, "Wait"); + closefd(&h->fds[1]); - haproxy_stop(h); + if (!h->opt_check_mode) { + assert(h->pid > 0); + vtc_log(h->vl, 2, "Stop HAproxy pid=%ld", (long)h->pid); + h->kill_status = kill(h->pid, HAPROXY_SIGNAL); + h->kill_errno = errno; + h->expect_signal = -HAPROXY_SIGNAL; + // XXX: loop over kills to ESRCH ? + } - haproxy_cleanup(h, 0); + AZ(pthread_join(h->tp, &p)); + AZ(p); + closefd(&h->fds[0]); + if (!h->opt_daemon) { + vtc_wait4(h->vl, h->ppid, h->expect_exit, h->expect_signal, 0); + h->ppid = -1; + } + h->pid = -1; } #define HAPROXY_BE_FD_STR "fd@${" @@ -454,6 +389,22 @@ haproxy_build_backends(const struct haproxy *h, const char *vsb_data) return (0); } +static void +haproxy_check_conf(struct haproxy *h, const char *expect) +{ + + h->msgs = VSB_new_auto(); + AN(h->msgs); + h->opt_check_mode = 1; + haproxy_start(h); + haproxy_wait(h); + AZ(VSB_finish(h->msgs)); + if (strstr(VSB_data(h->msgs), expect) == NULL) + vtc_fatal(h->vl, "Did not find expected string '%s'", expect); + vtc_log(h->vl, 2, "Found expected '%s'", expect); + VSB_destroy(&h->msgs); +} + /********************************************************************** * Write a configuration for HAProxy instance. */ @@ -498,7 +449,9 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) * * To define a haproxy server, you'll use this syntax:: * - * haproxy hNAME [-arg STRING] [-conf[+vcl] STRING] + * haproxy hNAME -conf-OK CONFIG + * haproxy hNAME -conf-BAD ERROR CONFIG + * haproxy hNAME [-D] [-W] [-arg STRING] [-conf[+vcl] STRING] * * The first ``haproxy hNAME`` invocation will start the haproxy master * process in the background, waiting for the ``-start`` switch to actually @@ -509,6 +462,22 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) * hNAME * Identify the HAProxy server with a string, it must starts with 'h'. * + * \-conf-OK CONFIG + * Run haproxy in '-c' mode to check config is OK + * stdout/stderr should contain 'Configuration file is valid' + * The exit code should be 0. + * + * \-conf-BAD ERROR CONFIG + * Run haproxy in '-c' mode to check config is BAD. + * "ERROR" should be part of the diagnostics on stdout/stderr. + * The exit code should be 1. + * + * \-D + * Run HAproxy in daemon mode. If not given '-d' mode used. + * + * \-W + * Enable HAproxy in Worker mode. + * * \-arg STRING * Pass an argument to haproxy, for example "-h simple_list". * @@ -519,26 +488,12 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) * Specify the configuration to be loaded by this HAProxy instance, * all server instances will be automatically appended * - * You can decide to start the HAProxy instance and/or wait for several events:: - * - * haproxy hNAME [-start] [-wait-running] [-wait-stopped] - * * \-start * Start this HAProxy instance. * - * \-stop + * \-wait * Stop this HAProxy instance. * - * \-wait-running - * Wait for that instance to terminate. - * - * \-wait-stopped - * Wait for that instance to terminate. - * - * \-cleanup - * Once HAProxy is stopped, clean everything after it. This is only used - * in very few tests and you should never need it. - * * \-expectexit NUMBER * Expect haproxy to exit(3) with this value * @@ -580,6 +535,33 @@ cmd_haproxy(CMD_ARGS) for (; *av != NULL; av++) { if (vtc_error) break; + + if (!strcmp(*av, "-conf-OK")) { + AN(av[1]); + haproxy_write_conf(h, av[1], 0); + av++; + haproxy_check_conf(h, HAPROXY_GOOD_CONF); + continue; + } + if (!strcmp(*av, "-conf-BAD")) { + AN(av[1]); + AN(av[2]); + haproxy_write_conf(h, av[2], 0); + h->expect_exit = 1; + haproxy_check_conf(h, av[1]); + av += 2; + continue; + } + + if (!strcmp(*av, HAPROXY_OPT_DAEMON)) { + h->opt_daemon = 1; + continue; + } + if (!strcmp(*av, HAPROXY_OPT_WORKER)) { + h->opt_worker = 1; + continue; + } + if (!strcmp(*av, "-arg")) { AN(av[1]); AZ(h->pid); @@ -588,6 +570,7 @@ cmd_haproxy(CMD_ARGS) av++; continue; } + if (!strcmp(*av, "-conf")) { AN(av[1]); haproxy_write_conf(h, av[1], 0); @@ -600,6 +583,7 @@ cmd_haproxy(CMD_ARGS) av++; continue; } + if (!strcmp(*av, "-expectexit")) { h->expect_exit = strtoul(av[1], NULL, 0); av++; @@ -610,7 +594,7 @@ cmd_haproxy(CMD_ARGS) continue; } if (!strcmp(*av, "-wait")) { - wait_stopped(h); + haproxy_wait(h); continue; } vtc_fatal(h->vl, "Unknown haproxy argument: %s", *av); From fgsch at lodoss.net Thu Aug 16 08:52:29 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:29 +0000 (UTC) Subject: [6.0] a3f94bde6 Don't call VTCP_hisname() on UDS connections Message-ID: <20180816085229.3A33C9881B@lists.varnish-cache.org> commit a3f94bde6c004cb97ec35fd6813859ce0cc09e73 Author: Federico G. Schwindt Date: Thu Mar 29 14:19:37 2018 -0300 Don't call VTCP_hisname() on UDS connections diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index a339a7f5f..1307cd5fb 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -242,8 +242,11 @@ server_thread(void *priv) fd = accept(s->sock, addr, &l); if (fd < 0) vtc_fatal(vl, "Accept failed: %s", strerror(errno)); - VTCP_hisname(fd, abuf, sizeof abuf, pbuf, sizeof pbuf); - vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf); + if (*s->listen != '/') { + VTCP_hisname(fd, abuf, sizeof abuf, pbuf, sizeof pbuf); + vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf); + } else + vtc_log(vl, 3, "accepted fd %d 0.0.0.0 0", fd); fd = http_process(vl, s->spec, fd, &s->sock, s->listen); vtc_log(vl, 3, "shutting fd %d", fd); j = shutdown(fd, SHUT_WR); From fgsch at lodoss.net Thu Aug 16 08:52:29 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:29 +0000 (UTC) Subject: [6.0] 1ed2bb63a Correct assert Message-ID: <20180816085229.6284998831@lists.varnish-cache.org> commit 1ed2bb63a5bac9bf0843603f0e00948a38349e92 Author: Federico G. Schwindt Date: Fri Mar 30 10:25:11 2018 -0300 Correct assert diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index 50cdd9a65..799d10903 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -212,7 +212,7 @@ h2_b64url_settings(struct h2_sess *h2, struct req *req) if (q == NULL) return (-1); i = q - s; - assert(i >= 0 && i <= 63); + assert(i >= 0 && i <= 64); x <<= 6; x |= i; n += 6; From fgsch at lodoss.net Thu Aug 16 08:52:29 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:29 +0000 (UTC) Subject: [6.0] a581aa81d Don't report on vsmw_newcluster for now Message-ID: <20180816085229.8D1C09884A@lists.varnish-cache.org> commit a581aa81d3d06f14041f0b96be2efe842a94615b Author: Federico G. Schwindt Date: Fri Mar 30 11:33:21 2018 -0300 Don't report on vsmw_newcluster for now diff --git a/tools/lsan.suppr b/tools/lsan.suppr index 5cef2ee51..67ea016a0 100644 --- a/tools/lsan.suppr +++ b/tools/lsan.suppr @@ -17,3 +17,5 @@ leak:hpack/vhp_gen_hufdec.c leak:binheap_new # ev leak:mct_callback +# +leak:vsmw_newcluster From fgsch at lodoss.net Thu Aug 16 08:52:29 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:29 +0000 (UTC) Subject: [6.0] aa69c9a4e Test persistent storage under Travis Message-ID: <20180816085229.B8B929886E@lists.varnish-cache.org> commit aa69c9a4ecf45e19d855404451e4044d4d8801cf Author: Federico G. Schwindt Date: Fri Mar 30 11:35:26 2018 -0300 Test persistent storage under Travis diff --git a/.travis.yml b/.travis.yml index 4b310bee1..f71674461 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ before_install: sudo apt-get update; sudo apt-get install -y clang-$CLANG llvm-$CLANG; export CC=clang-$CLANG; - export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector ${SAN_FLAGS}"; + export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage ${SAN_FLAGS}"; export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0; export LSAN_OPTIONS=abort_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/lsan.suppr; export TSAN_OPTIONS=abort_on_error=1,halt_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/tsan.suppr; From fgsch at lodoss.net Thu Aug 16 08:52:29 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:29 +0000 (UTC) Subject: [6.0] 047a30e2b Plug tiny leak Message-ID: <20180816085229.E730C9887E@lists.varnish-cache.org> commit 047a30e2b5025d4654f94b6f09c47c043679daf3 Author: Federico G. Schwindt Date: Fri Mar 30 11:36:24 2018 -0300 Plug tiny leak diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index fe16d8927..981c5bfea 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -414,6 +414,7 @@ mgt_launch_child(struct cli *cli) return; } + free(p); child_state = CH_RUNNING; } From fgsch at lodoss.net Thu Aug 16 08:52:30 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:30 +0000 (UTC) Subject: [6.0] 52e8fb15a Also exclude backtrace_symbols Message-ID: <20180816085230.1C77B98894@lists.varnish-cache.org> commit 52e8fb15a6a39be0820c5449174f2441b29448ee Author: Federico G. Schwindt Date: Fri Mar 30 12:16:58 2018 -0300 Also exclude backtrace_symbols diff --git a/tools/lsan.suppr b/tools/lsan.suppr index 67ea016a0..89bc6c707 100644 --- a/tools/lsan.suppr +++ b/tools/lsan.suppr @@ -18,4 +18,6 @@ leak:binheap_new # ev leak:mct_callback # +leak:backtrace_symbols +# leak:vsmw_newcluster From fgsch at lodoss.net Thu Aug 16 08:52:30 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:30 +0000 (UTC) Subject: [6.0] a3696e650 Plug another tiny leak Message-ID: <20180816085230.469ED988AE@lists.varnish-cache.org> commit a3696e650951f397b2952c62011acb73f59520fe Author: Federico G. Schwindt Date: Fri Mar 30 15:34:16 2018 -0300 Plug another tiny leak diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c index db42d31bb..69f319509 100644 --- a/bin/varnishadm/varnishadm.c +++ b/bin/varnishadm/varnishadm.c @@ -282,6 +282,7 @@ interactive(int sock) } } } + free(answer); cli_write(sock, "banner\n"); while (1) { i = poll(fds, 2, -1); From fgsch at lodoss.net Thu Aug 16 08:52:30 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:30 +0000 (UTC) Subject: [6.0] 71519e2d9 Tweak this parameter regardless of configure args Message-ID: <20180816085230.6A4BC988C6@lists.varnish-cache.org> commit 71519e2d9d99eb3f52af0ff1677988a3c4cfbf40 Author: Federico G. Schwindt Date: Sat Mar 31 10:32:01 2018 -0300 Tweak this parameter regardless of configure args diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 2d262e9a7..0797bfcfe 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -510,7 +510,8 @@ MCF_InitParams(struct cli *cli) low = sysconf(_SC_THREAD_STACK_MIN); MCF_ParamConf(MCF_MINIMUM, "thread_pool_stack", "%jdb", (intmax_t)low); -#if defined(__SANITIZER) +#if defined(__SANITIZER) || \ + (defined(__has_feature) && __has_feature(address_sanitizer)) def = 92 * 1024; #else def = 48 * 1024; From fgsch at lodoss.net Thu Aug 16 08:52:30 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:30 +0000 (UTC) Subject: [6.0] 998d7b2e5 Rework to make gcc happy Message-ID: <20180816085230.91DD5988DC@lists.varnish-cache.org> commit 998d7b2e5078b8ac7e68727b78a92dd4aa342535 Author: Federico G. Schwindt Date: Sat Mar 31 11:27:28 2018 -0300 Rework to make gcc happy diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index 0797bfcfe..139814c09 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -43,6 +43,10 @@ #include "vav.h" #include "vcli_serve.h" +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif + struct plist { unsigned magic; #define PLIST_MAGIC 0xbfc3ea16 @@ -510,8 +514,7 @@ MCF_InitParams(struct cli *cli) low = sysconf(_SC_THREAD_STACK_MIN); MCF_ParamConf(MCF_MINIMUM, "thread_pool_stack", "%jdb", (intmax_t)low); -#if defined(__SANITIZER) || \ - (defined(__has_feature) && __has_feature(address_sanitizer)) +#if defined(__SANITIZER) || __has_feature(address_sanitizer) def = 92 * 1024; #else def = 48 * 1024; From fgsch at lodoss.net Thu Aug 16 08:52:30 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:30 +0000 (UTC) Subject: [6.0] cd6b026ad Enable coredump with ASAN Message-ID: <20180816085230.C8B05988FA@lists.varnish-cache.org> commit cd6b026ad8bb8495d127b2f4e6fc2f5172a69951 Author: Federico G. Schwindt Date: Mon Apr 2 15:06:45 2018 +0100 Enable coredump with ASAN Mostly adding it here for documentation purposes. diff --git a/.travis.yml b/.travis.yml index f71674461..f3d5a2b68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ before_install: sudo apt-get install -y clang-$CLANG llvm-$CLANG; export CC=clang-$CLANG; export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage ${SAN_FLAGS}"; - export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0; + export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0,disable_coredump=0; export LSAN_OPTIONS=abort_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/lsan.suppr; export TSAN_OPTIONS=abort_on_error=1,halt_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/tsan.suppr; export UBSAN_OPTIONS=halt_on_error=1,print_stacktrace=1,use_sigaltstack=0,suppressions=$(pwd)/tools/ubsan.suppr; From geoff at uplex.de Thu Aug 16 08:52:30 2018 From: geoff at uplex.de (Geoff Simmons) Date: Thu, 16 Aug 2018 08:52:30 +0000 (UTC) Subject: [6.0] dfcb080d3 Improved vtc test for vmod_proxy Message-ID: <20180816085230.F1F2198924@lists.varnish-cache.org> commit dfcb080d3a514324f314fa325e4b46152861a230 Author: Emmanuel Hocdet Date: Thu Mar 15 15:15:16 2018 +0100 Improved vtc test for vmod_proxy diff --git a/bin/varnishtest/tests/o00005.vtc b/bin/varnishtest/tests/o00005.vtc index 49cb0efb3..d40e3538d 100644 --- a/bin/varnishtest/tests/o00005.vtc +++ b/bin/varnishtest/tests/o00005.vtc @@ -9,18 +9,30 @@ varnish v1 -proto "PROXY" -vcl+backend { import proxy; sub vcl_deliver { + if (proxy.is_ssl()) { + set resp.http.is_ssl = "yes"; + } + if (!proxy.client_has_cert_sess()) { + set resp.http.client_has_cert_sess = "no"; + } + if (!proxy.client_has_cert_conn()) { + set resp.http.client_has_cert_conn = "no"; + } if (proxy.ssl_verify_result() == 0) { set resp.http.verify = "ok"; } set resp.http.alpn = proxy.alpn(); + set resp.http.authority = proxy.authority(); set resp.http.ssl-version = proxy.ssl_version(); set resp.http.cipher = proxy.ssl_cipher(); set resp.http.key = proxy.cert_key(); set resp.http.sign = proxy.cert_sign(); + set resp.http.cn = proxy.client_cert_cn(); } } -start client c1 { + # PROXY2 with CRC32C TLV sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a 21 11 00 65" sendhex "d9 46 b5 21 5f 8e a8 22 ed 96 01 bb 03 00 04 95" sendhex "03 ee 75 01 00 02 68 32 02 00 0a 68 6f 63 64 65" @@ -32,10 +44,29 @@ client c1 { txreq rxresp expect resp.status == 200 + expect resp.http.is_ssl == yes + expect resp.http.client_has_cert_sess == no + expect resp.http.client_has_cert_conn == no expect resp.http.verify == ok expect resp.http.alpn == h2 + expect resp.http.authority == hocdet.net expect resp.http.ssl-version == TLSv1.3 expect resp.http.cipher == AEAD-AES128-GCM-SHA256 expect resp.http.key == EC256 expect resp.http.sign == RSA-SHA256 + expect resp.http.cn == "" +} -run + +client c1 { + # PROXY2 with CRC32C TLV and bad checksum + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a 21 11 00 65" + sendhex "d9 46 b5 21 5f 8e a8 22 ed 96 01 bb 03 00 04 95" + sendhex "03 ee 75 01 00 02 68 32 02 00 0a 68 6f 63 64 65" + sendhex "74 2e 6e 65 74 20 00 3d 01 00 00 00 00 21 00 07" + sendhex "54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24" + sendhex "00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41" + sendhex "45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53" + sendhex "48 41 32 35 35" + txreq + expect_close } -run From fgsch at lodoss.net Thu Aug 16 08:52:31 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] e5555da4b Run make distcheck on PRs Message-ID: <20180816085231.234DD9892F@lists.varnish-cache.org> commit e5555da4b39574d8568429b372ecc128541c2cee Author: Federico G. Schwindt Date: Mon Apr 2 16:39:24 2018 +0100 Run make distcheck on PRs Also give irc notifications a try. Discussed with phk and geoff. diff --git a/.travis.yml b/.travis.yml index f3d5a2b68..9eb8e4a39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,13 @@ addons: apt: packages: - python-docutils +notifications: + irc: + channels: + - "irc.linpro.no#varnish-hacking" + on_success: change + use_notice: true + skip_join: true before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; @@ -50,4 +57,5 @@ before_install: script: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PYTHONPATH=`brew --prefix`/lib/python2.7/site-packages; fi - - make -j3 check VERBOSE=1 + - if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then make -j3 distcheck; fi + - if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then make -j3 check VERBOSE=1; fi From nils.goroll at uplex.de Thu Aug 16 08:52:31 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] b40aa2cea disambiguate VTLA variable names - vcp is now connection pooling Message-ID: <20180816085231.4560098949@lists.varnish-cache.org> commit b40aa2cea0ec1100abc58ae9555db3e35922d708 Author: Nils Goroll Date: Sat Mar 31 15:41:37 2018 +0200 disambiguate VTLA variable names - vcp is now connection pooling diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 5ac0a0065..6001d323b 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -686,12 +686,12 @@ VRT_VSM_Cluster_New(VRT_CTX, size_t sz) } void v_matchproto_() -VRT_VSM_Cluster_Destroy(VRT_CTX, struct vsmw_cluster **vcp) +VRT_VSM_Cluster_Destroy(VRT_CTX, struct vsmw_cluster **vsmcp) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - AN(vcp); - VSMW_DestroyCluster(heritage.proc_vsmw, vcp); + AN(vsmcp); + VSMW_DestroyCluster(heritage.proc_vsmw, vsmcp); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/common/common_vsmw.c b/bin/varnishd/common/common_vsmw.c index 8501cc414..0aa5477e6 100644 --- a/bin/varnishd/common/common_vsmw.c +++ b/bin/varnishd/common/common_vsmw.c @@ -275,15 +275,15 @@ VSMW_NewCluster(struct vsmw *vsmw, size_t len, const char *pfx) } void -VSMW_DestroyCluster(struct vsmw *vsmw, struct vsmw_cluster **vcp) +VSMW_DestroyCluster(struct vsmw *vsmw, struct vsmw_cluster **vsmcp) { struct vsmw_cluster *vc; vsmw_lock(); CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC); - AN(vcp); - vc = *vcp; - *vcp = NULL; + AN(vsmcp); + vc = *vsmcp; + *vsmcp = NULL; CHECK_OBJ_NOTNULL(vc, VSMW_CLUSTER_MAGIC); if (vc->cseg != NULL) { From nils.goroll at uplex.de Thu Aug 16 08:52:31 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] aab5dda67 more details to fetcherror Message-ID: <20180816085231.69FBC98960@lists.varnish-cache.org> commit aab5dda67d83bf0f4999e1718aaedbb810c1ead7 Author: Nils Goroll Date: Sun Apr 1 14:45:34 2018 +0200 more details to fetcherror Ref #2622 diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 392baba1d..acef64826 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -33,6 +33,7 @@ #include "config.h" #include +#include #include "cache_varnishd.h" @@ -116,7 +117,8 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo, pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh); if (pfd == NULL) { VSLb(bo->vsl, SLT_FetchError, - "backend %s: fail", bp->director->display_name); + "backend %s: fail errno %d (%s)", + bp->director->display_name, errno, strerror(errno)); // XXX: Per backend stats ? VSC_C_main->backend_fail++; bo->htc = NULL; From fgsch at lodoss.net Thu Aug 16 08:52:31 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] 18920d641 Also install python-sphinx Message-ID: <20180816085231.8AFEC9896D@lists.varnish-cache.org> commit 18920d641c6cdf5c401f7084db13575d289aad02 Author: Federico G. Schwindt Date: Tue Apr 3 10:46:47 2018 +0100 Also install python-sphinx Required for make distcheck. Spotted by geoff. diff --git a/.travis.yml b/.travis.yml index 9eb8e4a39..858d0799f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ addons: apt: packages: - python-docutils + - python-sphinx notifications: irc: channels: From fgsch at lodoss.net Thu Aug 16 08:52:31 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] 78866f7b4 Make "make distcheck" happy under osx Message-ID: <20180816085231.B0D7998986@lists.varnish-cache.org> commit 78866f7b4f2ddac2b72d9e30c93c6368cfdd88bf Author: Federico G. Schwindt Date: Tue Apr 3 14:31:10 2018 +0100 Make "make distcheck" happy under osx Also report success/failure earlier. diff --git a/.travis.yml b/.travis.yml index 858d0799f..2ff305cec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ sudo: required language: c matrix: + fast_finish: true include: - os: linux dist: trusty @@ -34,7 +35,7 @@ notifications: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; - brew install docutils nghttp2; + brew install docutils sphinx-doc nghttp2; fi - if [[ -n "$CLANG" ]]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | From phk at FreeBSD.org Thu Aug 16 08:52:31 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] 7a881b177 Change how gcov is run Message-ID: <20180816085231.D2989989B2@lists.varnish-cache.org> commit 7a881b177c5b77597398b333f557a8846337fc88 Author: Poul-Henning Kamp Date: Wed Apr 4 06:53:50 2018 +0000 Change how gcov is run diff --git a/tools/vtest.sh b/tools/vtest.sh index 92020396e..1508c2fca 100755 --- a/tools/vtest.sh +++ b/tools/vtest.sh @@ -149,14 +149,6 @@ makegcov () ( set -x cd "${SRCDIR}" - export CFLAGS="-fprofile-arcs -ftest-coverage -fstack-protector -DDONT_DLCLOSE_VMODS" CC=gcc49 - export MAKEFLAGS=-j1 - umask 0 - - find . -name '*.gc??' -print | xargs rm -f - - sh autogen.des || exit 1 - make || exit 1 if [ `id -u` -eq 0 ] ; then @@ -180,14 +172,19 @@ failedtests () ( cd "${SRCDIR}" + VTCDIR=bin/varnishtest/tests + VERSION=`./configure --version | awk 'NR == 1 {print $NF}'` LOGDIR="varnish-$VERSION/_build/sub/bin/varnishtest/tests" - VTCDIR=bin/varnishtest/tests # cope with older automake, remove the sub directory test ! -d $LOGDIR && LOGDIR="varnish-$VERSION/_build/bin/varnishtest/tests" + # gcov situation + test ! -d $LOGDIR && + LOGDIR="bin/varnishtest/tests" + grep -l ':test-result: FAIL' "$LOGDIR"/*.trs | while read trs do @@ -201,14 +198,16 @@ failedtests () ( done ) - +if $enable_gcov ; then + export CC=gcc6 + export CFLAGS="-fprofile-arcs -ftest-coverage -fstack-protector -DDONT_DLCLOSE_VMODS" + export MAKEFLAGS=-j1 +fi orev=000 waitnext=${WAITBAD} i=0 -last_day=`date +%d` - while [ $MAXRUNS -eq 0 ] || [ $i -lt $MAXRUNS ] do i=$((i + 1)) @@ -231,19 +230,6 @@ do rm -rf "${REPORTDIR}" mkdir "${REPORTDIR}" - if ! $enable_gcov ; then - do_gcov=false - elif [ -f _force_gcov ] ; then - do_gcov=true - rm -f _force_gcov - elif [ `date +%d` == $last_day ] ; then - do_gcov=false - elif [ `date +%H` -lt 3 ] ; then - do_gcov=false - else - do_gcov=true - fi - echo "VTEST 1.04" > ${VTEST_REPORT} echo "DATE `date +%s`" >> ${VTEST_REPORT} echo "BRANCH trunk" >> ${VTEST_REPORT} @@ -257,20 +243,24 @@ do fi echo "MESSAGE ${MESSAGE}" >> ${VTEST_REPORT} echo "GITREV $rev" >> ${VTEST_REPORT} + + find . -name '*.gc??' -print | xargs rm -f + if ! autogen >> ${REPORTDIR}/_autogen 2>&1 ; then echo "AUTOGEN BAD" >> ${VTEST_REPORT} echo "MANIFEST _autogen" >> ${VTEST_REPORT} else echo "AUTOGEN GOOD" >> ${VTEST_REPORT} - if $do_gcov ; then - last_day=`date +%d` + if $enable_gcov ; then if makegcov >> ${REPORTDIR}/_makegcov 2>&1 ; then mv ${SRCDIR}/_gcov ${REPORTDIR}/ echo "MAKEGCOV GOOD" >> ${VTEST_REPORT} echo "MANIFEST _gcov" >> ${VTEST_REPORT} + waitnext=${WAITGOOD} else echo "MAKEGCOV BAD" >> ${VTEST_REPORT} echo "MANIFEST _makegcov" >> ${VTEST_REPORT} + failedtests >> ${VTEST_REPORT} fi elif ! makedistcheck >> ${REPORTDIR}/_makedistcheck 2>&1 ; then echo "MAKEDISTCHECK BAD" >> ${VTEST_REPORT} From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:31 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:31 +0000 (UTC) Subject: [6.0] 73641bf3c Update to gcc6 Message-ID: <20180816085232.095D0989C5@lists.varnish-cache.org> commit 73641bf3c7a268ef4094f6efa5097ef63dc92df0 Author: Poul-Henning Kamp Date: Wed Apr 4 10:10:29 2018 +0000 Update to gcc6 diff --git a/tools/gcov_digest.py b/tools/gcov_digest.py index 4b241873f..fd595c9c9 100644 --- a/tools/gcov_digest.py +++ b/tools/gcov_digest.py @@ -33,7 +33,7 @@ found in a subdirectory tree. Options: -g gcov-program - default:gcov49 + default:gcov6 -o output-filename default: stdout @@ -180,7 +180,7 @@ if __name__ == "__main__": optlist, args = getopt.getopt(sys.argv[1:], "g:o:x:") fo = sys.stdout - gcovprog = "gcov49" + gcovprog = "gcov6 for f, v in optlist: if f == '-o' and v == '-': From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:32 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:32 +0000 (UTC) Subject: [6.0] 396ac85db Typo Message-ID: <20180816085232.2A85A989D9@lists.varnish-cache.org> commit 396ac85db71e247ab7de1389de5eb5f0a0843f21 Author: Poul-Henning Kamp Date: Wed Apr 4 11:56:33 2018 +0000 Typo diff --git a/tools/gcov_digest.py b/tools/gcov_digest.py index fd595c9c9..138f7e8cf 100644 --- a/tools/gcov_digest.py +++ b/tools/gcov_digest.py @@ -180,7 +180,7 @@ if __name__ == "__main__": optlist, args = getopt.getopt(sys.argv[1:], "g:o:x:") fo = sys.stdout - gcovprog = "gcov6 + gcovprog = "gcov6" for f, v in optlist: if f == '-o' and v == '-': From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:32 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:32 +0000 (UTC) Subject: [6.0] fc0ca5fb7 improve do_stream documentation Message-ID: <20180816085232.4ED7E989F4@lists.varnish-cache.org> commit fc0ca5fb7a1e6c4a6a501a8290e7db11124f4ef4 Author: Nils Goroll Date: Wed Apr 4 14:56:59 2018 +0200 improve do_stream documentation diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index c4ded7c3e..85c11fb22 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -719,13 +719,17 @@ beresp.do_stream Writable from: vcl_backend_response, vcl_backend_error + Default: true + Deliver the object to the client while fetching the whole object into varnish. For uncacheable objects, storage for parts of the body which have been sent to the client may get freed early, depending on the storage engine used. - + + This variable has no effect if do_esi is true and when the + response body is empty. beresp.do_gzip From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:32 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:32 +0000 (UTC) Subject: [6.0] b5196b5d3 common sense "and" == boolean logic "or" Message-ID: <20180816085232.7831C98A0A@lists.varnish-cache.org> commit b5196b5d30d49d6ae0e43cc4a2aea8f6221e87b7 Author: Nils Goroll Date: Wed Apr 4 15:30:14 2018 +0200 common sense "and" == boolean logic "or" diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 85c11fb22..6df36351e 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -728,7 +728,7 @@ beresp.do_stream have been sent to the client may get freed early, depending on the storage engine used. - This variable has no effect if do_esi is true and when the + This variable has no effect if do_esi is true or when the response body is empty. beresp.do_gzip From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:32 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:32 +0000 (UTC) Subject: [6.0] 1dca4a36f Use libumem only as a storage allocator, not to override malloc etc. Message-ID: <20180816085232.A9ED498A29@lists.varnish-cache.org> commit 1dca4a36f692b79fa37b4ca0e23340e09f9f5765 Author: Geoff Simmons Date: Mon Apr 2 22:05:05 2018 +0200 Use libumem only as a storage allocator, not to override malloc etc. We do this by not linking with libumem, but rather using dlopen/dlsym to load the slab allocator interface, which is used by the stevedore. diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 739b16cfe..1e8640e07 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -169,7 +169,7 @@ varnishd_LDADD = \ @SAN_LDFLAGS@ \ @JEMALLOC_LDADD@ \ @PCRE_LIBS@ \ - ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} ${UMEM_LIBS} + ${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${RT_LIBS} ${LIBM} noinst_PROGRAMS = vhp_gen_hufdec vhp_gen_hufdec_SOURCES = hpack/vhp_gen_hufdec.c diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index 05b4c61ab..237a45bd0 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -136,7 +136,7 @@ usage(void) printf(FMT, "-s [name=]kind[,options]", "Storage specification"); printf(FMT, "", "Can be specified multiple times."); -#ifdef HAVE_LIBUMEM +#ifdef HAVE_UMEM_H printf(FMT, "", " -s default (=umem)"); printf(FMT, "", " -s umem"); #else diff --git a/bin/varnishd/storage/mgt_stevedore.c b/bin/varnishd/storage/mgt_stevedore.c index ba7e5b112..a37ddf335 100644 --- a/bin/varnishd/storage/mgt_stevedore.c +++ b/bin/varnishd/storage/mgt_stevedore.c @@ -126,7 +126,7 @@ static const struct choice STV_choice[] = { { "deprecated_persistent", &smp_stevedore }, { "persistent", &smp_fake_stevedore }, #endif -#if defined(HAVE_LIBUMEM) +#if defined(HAVE_UMEM_H) { "umem", &smu_stevedore }, { "default", &smu_stevedore }, #else diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c index afc277145..acb291a51 100644 --- a/bin/varnishd/storage/storage_umem.c +++ b/bin/varnishd/storage/storage_umem.c @@ -33,13 +33,14 @@ #include "config.h" -#if defined(HAVE_LIBUMEM) +#if defined(HAVE_UMEM_H) #include "cache/cache_varnishd.h" #include #include #include +#include #include "storage/storage.h" #include "storage/storage_simple.h" @@ -67,6 +68,30 @@ struct smu { struct smu_sc *sc; }; +/* + * We only want the umem slab allocator for cache storage, not also as a + * substitute for malloc and friends. So we don't link with libumem, but + * use dlopen/dlsym to get the slab allocator interface into function + * pointers. + */ +typedef void * (*umem_alloc_f)(size_t size, int flags); +typedef void (*umem_free_f)(void *buf, size_t size); +typedef umem_cache_t * (*umem_cache_create_f)(char *debug_name, size_t bufsize, + size_t align, umem_constructor_t *constructor, + umem_destructor_t *destructor, umem_reclaim_t *reclaim, + void *callback_data, vmem_t *source, int cflags); +typedef void (*umem_cache_destroy_f)(umem_cache_t *cache); +typedef void * (*umem_cache_alloc_f)(umem_cache_t *cache, int flags); +typedef void (*umem_cache_free_f)(umem_cache_t *cache, void *buffer); + +static void *libumem_hndl = NULL; +static umem_alloc_f umem_allocf = NULL; +static umem_free_f umem_freef = NULL; +static umem_cache_create_f umem_cache_createf = NULL; +static umem_cache_destroy_f umem_cache_destroyf = NULL; +static umem_cache_alloc_f umem_cache_allocf = NULL; +static umem_cache_free_f umem_cache_freef = NULL; + /* init required per cache get: smu->sz = size smu->s.ptr; @@ -142,14 +167,14 @@ smu_alloc(const struct stevedore *st, size_t size) * allocations growing another full page, just to accommodate the smu. */ - p = umem_alloc(size, UMEM_DEFAULT); + p = umem_allocf(size, UMEM_DEFAULT); if (p != NULL) { AN(smu_sc->smu_cache); - smu = umem_cache_alloc(smu_sc->smu_cache, UMEM_DEFAULT); + smu = umem_cache_allocf(smu_sc->smu_cache, UMEM_DEFAULT); if (smu != NULL) smu->s.ptr = p; else - umem_free(p, size); + umem_freef(p, size); } if (smu == NULL) { Lck_Lock(&smu_sc->smu_mtx); @@ -191,9 +216,9 @@ smu_free(struct storage *s) sc->stats->g_space += smu->sz; Lck_Unlock(&sc->smu_mtx); - umem_free(smu->s.ptr, smu->sz); + umem_freef(smu->s.ptr, smu->sz); smu_smu_init(smu, sc); - umem_cache_free(sc->smu_cache, smu); + umem_cache_freef(sc->smu_cache, smu); } static VCL_BYTES v_matchproto_(stv_var_used_space) @@ -235,6 +260,28 @@ smu_init(struct stevedore *parent, int ac, char * const *av) if (ac == 0 || *av[0] == '\0') return; + /* Check if these load in the management process. */ + (void) dlerror(); + if ((libumem_hndl = dlopen("libumem.so", RTLD_NOW)) == NULL) + ARGV_ERR("(-sumem) cannot open libumem.so: %s", dlerror()); + +#define DLSYM_UMEM(fptr,sym) \ + do { \ + (void) dlerror(); \ + if ((fptr = dlsym(libumem_hndl, #sym)) == NULL) \ + ARGV_ERR("(-sumem) cannot find symbol " #sym ": %s", \ + dlerror()); \ + } while(0) + + DLSYM_UMEM(umem_allocf, umem_alloc); + DLSYM_UMEM(umem_freef, umem_free); + DLSYM_UMEM(umem_cache_createf, umem_cache_create); + DLSYM_UMEM(umem_cache_destroyf, umem_cache_destroy); + DLSYM_UMEM(umem_cache_allocf, umem_cache_alloc); + DLSYM_UMEM(umem_cache_freef, umem_cache_free); + +#undef DLSYM_UMEM + e = VNUM_2bytes(av[0], &u, 0); if (e != NULL) ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); @@ -262,7 +309,32 @@ smu_open(struct stevedore *st) if (smu_sc->smu_max != SIZE_MAX) smu_sc->stats->g_space = smu_sc->smu_max; - smu_sc->smu_cache = umem_cache_create(st->ident, + /* + * Load the symbols for use in the child process, assert if they + * fail to load. + */ + if (libumem_hndl == NULL) { + libumem_hndl = dlopen("libumem.so", RTLD_NOW); + AN(libumem_hndl); + +#define DLSYM_UMEM(fptr,sym) \ + do { \ + fptr = dlsym(libumem_hndl, #sym); \ + AN(fptr); \ + } while(0) + + DLSYM_UMEM(umem_allocf, umem_alloc); + DLSYM_UMEM(umem_freef, umem_free); + DLSYM_UMEM(umem_cache_createf, umem_cache_create); + DLSYM_UMEM(umem_cache_destroyf, umem_cache_destroy); + DLSYM_UMEM(umem_cache_allocf, umem_cache_alloc); + DLSYM_UMEM(umem_cache_freef, umem_cache_free); + +#undef DLSYM_UMEM + + } + + smu_sc->smu_cache = umem_cache_createf(st->ident, sizeof(struct smu), 0, // align smu_smu_constructor, @@ -285,7 +357,7 @@ smu_close(const struct stevedore *st, int warn) CAST_OBJ_NOTNULL(smu_sc, st->priv, SMU_SC_MAGIC); if (warn) return; - umem_cache_destroy(smu_sc->smu_cache); + umem_cache_destroyf(smu_sc->smu_cache); smu_sc->smu_cache = NULL; /* diff --git a/configure.ac b/configure.ac index e16e2d5d4..ad2850737 100644 --- a/configure.ac +++ b/configure.ac @@ -83,7 +83,7 @@ _VARNISH_CHECK_LIB(nsl, getaddrinfo) AC_SUBST(NET_LIBS, "${SOCKET_LIBS} ${NSL_LIBS}") # Userland slab allocator from Solaris, ported to other systems -AC_CHECK_HEADERS([umem.h], [_VARNISH_CHECK_LIB(umem, umem_alloc)]) +AC_CHECK_HEADERS([umem.h]) # XXX: This _may_ be for OS/X AC_CHECK_LIBM From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:32 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:32 +0000 (UTC) Subject: [6.0] 2adac3d59 umem: test-load libumem in a separate namespace in the management process Message-ID: <20180816085232.E3F9D98A4B@lists.varnish-cache.org> commit 2adac3d59c4904027254656b3a6f13b4ab8aadf6 Author: Nils Goroll Date: Wed Apr 4 09:21:11 2018 +0200 umem: test-load libumem in a separate namespace in the management process libumem's atfork handler will redefine malloc() and friends so if we load it in the manager, we cannot confine its use to the stevedore diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c index acb291a51..7464a199c 100644 --- a/bin/varnishd/storage/storage_umem.c +++ b/bin/varnishd/storage/storage_umem.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "storage/storage.h" #include "storage/storage_simple.h" @@ -262,7 +263,8 @@ smu_init(struct stevedore *parent, int ac, char * const *av) /* Check if these load in the management process. */ (void) dlerror(); - if ((libumem_hndl = dlopen("libumem.so", RTLD_NOW)) == NULL) + libumem_hndl = dlmopen(LM_ID_NEWLM, "libumem.so", RTLD_LAZY); + if (libumem_hndl == NULL) ARGV_ERR("(-sumem) cannot open libumem.so: %s", dlerror()); #define DLSYM_UMEM(fptr,sym) \ @@ -282,6 +284,9 @@ smu_init(struct stevedore *parent, int ac, char * const *av) #undef DLSYM_UMEM + AZ(dlclose(libumem_hndl)); + libumem_hndl = NULL; + e = VNUM_2bytes(av[0], &u, 0); if (e != NULL) ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:33 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:33 +0000 (UTC) Subject: [6.0] 9fd0d6b2e umem: default options, warn about umem loaded, lazy loading Message-ID: <20180816085233.2EFFE98A64@lists.varnish-cache.org> commit 9fd0d6b2e0a1a760a7d5e84a74157e6500ce1b2c Author: Nils Goroll Date: Wed Apr 4 16:13:14 2018 +0200 umem: default options, warn about umem loaded, lazy loading default options: For co-existance with libc malloc and potentially other allocators, we should use mmap() regions in favor of sbrk(). Also, libumem's perthread cache only makes sense when umem is actually used for all allocations and, by default, requires an additional massive 1MB per thread, which is totally out of scale with how we manage memory in varnish. if libumem is found to already be loaded, we cannot set its options, so warn about that fact. As we only use function pointers to libumem, lazy loading of symbols should be the better option. diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c index 7464a199c..54713316c 100644 --- a/bin/varnishd/storage/storage_umem.c +++ b/bin/varnishd/storage/storage_umem.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "storage/storage.h" #include "storage/storage_simple.h" @@ -93,6 +94,9 @@ static umem_cache_destroy_f umem_cache_destroyf = NULL; static umem_cache_alloc_f umem_cache_allocf = NULL; static umem_cache_free_f umem_cache_freef = NULL; +static const char * const def_umem_options = "perthread_cache=0,backend=mmap"; +static const char * const env_umem_options = "UMEM_OPTIONS"; + /* init required per cache get: smu->sz = size smu->s.ptr; @@ -240,9 +244,47 @@ smu_free_space(const struct stevedore *st) return (smu_sc->smu_max - smu_sc->smu_alloc); } +static void +smu_umem_loaded_warn(void) +{ + const char *e; + static int warned = 0; + + if (warned++) + return; + + fprintf(stderr, "notice:\tlibumem was already found to be loaded\n" + "\tand will likely be used for all allocations\n"); + + e = getenv(env_umem_options); + if (e == NULL || ! strstr(e, def_umem_options)) + fprintf(stderr, "\tit is recommended to set %s=%s " + "before starting varnish\n", + env_umem_options, def_umem_options); +} + +static int +smu_umem_loaded(void) +{ + void *h = NULL; + + h = dlopen("libumem.so", RTLD_NOLOAD); + if (h) { + AZ(dlclose(h)); + return (1); + } + + h = dlsym(RTLD_DEFAULT, "umem_alloc"); + if (h) + return (1); + + return (0); +} + static void smu_init(struct stevedore *parent, int ac, char * const *av) { + static int inited = 0; const char *e; uintmax_t u; struct smu_sc *sc; @@ -258,8 +300,25 @@ smu_init(struct stevedore *parent, int ac, char * const *av) if (ac > 1) ARGV_ERR("(-sumem) too many arguments\n"); - if (ac == 0 || *av[0] == '\0') - return; + if (ac == 1 && *av[0] != '\0') { + e = VNUM_2bytes(av[0], &u, 0); + if (e != NULL) + ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); + if ((u != (uintmax_t)(size_t)u)) + ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]); + if (u < 1024*1024) + ARGV_ERR("(-sumem) size \"%s\": too smull, " + "did you forget to specify M or G?\n", av[0]); + sc->smu_max = u; + } + + if (inited++) + return; + + if (smu_umem_loaded()) + smu_umem_loaded_warn(); + else + AZ(setenv(env_umem_options, def_umem_options, 0)); /* Check if these load in the management process. */ (void) dlerror(); @@ -286,17 +345,45 @@ smu_init(struct stevedore *parent, int ac, char * const *av) AZ(dlclose(libumem_hndl)); libumem_hndl = NULL; +} + +/* + * Load the symbols for use in the child process, assert if they fail to load. + */ +static void +smu_open_init(void) +{ + static int inited = 0; + + if (inited++) { + AN(libumem_hndl); + AN(umem_allocf); + return; + } + + if (smu_umem_loaded()) + smu_umem_loaded_warn(); + else + AN(getenv(env_umem_options)); + + AZ(libumem_hndl); + libumem_hndl = dlopen("libumem.so", RTLD_LAZY); + AN(libumem_hndl); - e = VNUM_2bytes(av[0], &u, 0); - if (e != NULL) - ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e); - if ((u != (uintmax_t)(size_t)u)) - ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]); - if (u < 1024*1024) - ARGV_ERR("(-sumem) size \"%s\": too smull, " - "did you forget to specify M or G?\n", av[0]); +#define DLSYM_UMEM(fptr,sym) \ + do { \ + fptr = dlsym(libumem_hndl, #sym); \ + AN(fptr); \ + } while(0) - sc->smu_max = u; + DLSYM_UMEM(umem_allocf, umem_alloc); + DLSYM_UMEM(umem_freef, umem_free); + DLSYM_UMEM(umem_cache_createf, umem_cache_create); + DLSYM_UMEM(umem_cache_destroyf, umem_cache_destroy); + DLSYM_UMEM(umem_cache_allocf, umem_cache_alloc); + DLSYM_UMEM(umem_cache_freef, umem_cache_free); + +#undef DLSYM_UMEM } static void v_matchproto_(storage_open_f) @@ -314,30 +401,7 @@ smu_open(struct stevedore *st) if (smu_sc->smu_max != SIZE_MAX) smu_sc->stats->g_space = smu_sc->smu_max; - /* - * Load the symbols for use in the child process, assert if they - * fail to load. - */ - if (libumem_hndl == NULL) { - libumem_hndl = dlopen("libumem.so", RTLD_NOW); - AN(libumem_hndl); - -#define DLSYM_UMEM(fptr,sym) \ - do { \ - fptr = dlsym(libumem_hndl, #sym); \ - AN(fptr); \ - } while(0) - - DLSYM_UMEM(umem_allocf, umem_alloc); - DLSYM_UMEM(umem_freef, umem_free); - DLSYM_UMEM(umem_cache_createf, umem_cache_create); - DLSYM_UMEM(umem_cache_destroyf, umem_cache_destroy); - DLSYM_UMEM(umem_cache_allocf, umem_cache_alloc); - DLSYM_UMEM(umem_cache_freef, umem_cache_free); - -#undef DLSYM_UMEM - - } + smu_open_init(); smu_sc->smu_cache = umem_cache_createf(st->ident, sizeof(struct smu), From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:33 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:33 +0000 (UTC) Subject: [6.0] afd267dc3 document umem specifics Message-ID: <20180816085233.64F2A98A76@lists.varnish-cache.org> commit afd267dc3feb8f79bed94b05a0cbd64797fdb01a Author: Nils Goroll Date: Wed Apr 4 16:47:45 2018 +0200 document umem specifics diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index b6d383a75..de7ee866f 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -320,6 +320,9 @@ The following storage types are available: umem is a storage backend which is more efficient than malloc on platforms where it is available. + See the section on umem in chapter `Storage backends` of `The + Varnish Users Guide` for details. + -s The file backend stores data in a file on disk. The file will be diff --git a/doc/sphinx/users-guide/storage-backends.rst b/doc/sphinx/users-guide/storage-backends.rst index a6311066f..3dd71408a 100644 --- a/doc/sphinx/users-guide/storage-backends.rst +++ b/doc/sphinx/users-guide/storage-backends.rst @@ -53,6 +53,8 @@ malloc's performance is bound to memory speed so it is very fast. If the dataset is bigger than available memory performance will depend on the operating systems ability to page effectively. +.. _guide-storage_umem: + umem ~~~~ @@ -69,6 +71,37 @@ implementations. In particular, `libumem`_ is included in the family of OpenSolaris descendent operating systems where jemalloc(3) is not commonly available. +If `libumem`_ is not used otherwise, varnish will only use it for +storage allocations and keep the default libc allocator for all other +varnish memory allocation purposes. + +If `libumem`_ is already loaded when varnish initializes, this message +is output:: + + notice: libumem was already found to be loaded + and will likely be used for all allocations + +to indicate that `libumem`_ will not only be used for storage. Likely +reasons for this to be the case are: + +* some library ``varnishd`` is linked against was linked against + `libumem`_ (most likely ``libpcre``, check with ``ldd``) + +* ``LD_PRELOAD_64=/usr/lib/amd64/libumem.so.1``, + ``LD_PRELOAD_32=/usr/lib/libumem.so.1`` or + ``LD_PRELOAD=/usr/lib/libumem.so.1`` is set + +varnish will also output this message to recommend settings for using +`libumem`_ for all allocations:: + + it is recommended to set UMEM_OPTIONS=perthread_cache=0,backend=mmap + before starting varnish + +This recommendation should be followed to achieve an optimal +`libumem`_ configuration for varnish. Setting this environment +variable before starting varnish is required becuase `libumem`_ cannot +be reconfigured once loaded. + .. _libumem: http://dtrace.org/blogs/ahl/2004/07/13/number-11-of-20-libumem/ file From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:33 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:33 +0000 (UTC) Subject: [6.0] e182cb5ba no detail too small Message-ID: <20180816085233.8E9DD98A8A@lists.varnish-cache.org> commit e182cb5baacbb9affc3d27ff1104e97cd8c59043 Author: Nils Goroll Date: Wed Apr 4 17:06:58 2018 +0200 no detail too small diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c index 54713316c..db8178ab8 100644 --- a/bin/varnishd/storage/storage_umem.c +++ b/bin/varnishd/storage/storage_umem.c @@ -307,7 +307,7 @@ smu_init(struct stevedore *parent, int ac, char * const *av) if ((u != (uintmax_t)(size_t)u)) ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]); if (u < 1024*1024) - ARGV_ERR("(-sumem) size \"%s\": too smull, " + ARGV_ERR("(-sumem) size \"%s\": too small, " "did you forget to specify M or G?\n", av[0]); sc->smu_max = u; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:33 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:33 +0000 (UTC) Subject: [6.0] 90ca9c45e Bite the bullet and import Ed Schouten's terminal emulation "Teken" Message-ID: <20180816085233.BBEBE98AA4@lists.varnish-cache.org> commit 90ca9c45e71b5d7c1333df1ef5b93f4c3f0e50c1 Author: Poul-Henning Kamp Date: Wed Apr 4 21:37:01 2018 +0000 Bite the bullet and import Ed Schouten's terminal emulation "Teken" This allows us to use TERM=xterm. diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index c2c81d79b..06f2259fe 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -30,6 +30,12 @@ varnishtest_SOURCES = \ cmds.h \ vmods.h \ vtc.h \ + teken.c \ + teken.h \ + teken_scs.h \ + teken_subr.h \ + teken_subr_compat.h \ + teken_wcwidth.h \ vtc.c \ vtc_barrier.c \ vtc_client.c \ @@ -51,7 +57,6 @@ varnishtest_SOURCES = \ vtc_proxy.c \ vtc_server.c \ vtc_subr.c \ - vtc_term.c \ vtc_varnish.c varnishtest_LDADD = \ @@ -67,4 +72,16 @@ varnishtest_CFLAGS = \ -DTOP_BUILDDIR='"${top_builddir}"' EXTRA_DIST = $(top_srcdir)/bin/varnishtest/tests/*.vtc \ - $(top_srcdir)/bin/varnishtest/tests/README + $(top_srcdir)/bin/varnishtest/tests/README \ + $(top_srcdir)/bin/varnishtest/gensequences \ + $(top_srcdir)/bin/varnishtest/sequences \ + $(top_srcdir)/bin/varnishtest/teken.3 + +teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences + awk -f $(srcdir)/gensequences $(srcdir)/sequences \ + > $(builddir)/teken_state.h + +BUILT_SOURCES = teken_state.h + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/bin/varnishtest/flint.lnt b/bin/varnishtest/flint.lnt index 25eace29a..fa51cc85b 100644 --- a/bin/varnishtest/flint.lnt +++ b/bin/varnishtest/flint.lnt @@ -1,4 +1,6 @@ ++libh(teken/teken.h) + // Tell FlexeLint when these don't return -function(exit, vtc_fatal) -function(__assert(1), vtc_log(2)) @@ -8,6 +10,8 @@ -emacro({779}, ENC) // String constant in comparison operator '!=' -emacro({506}, CHKFRAME) // Constant value Boolean +-esym(522, teken_subr_*) + -esym(850, av) -esym(534, snprintf) // Only for varnishtest, and not really nice diff --git a/bin/varnishtest/flint.sh b/bin/varnishtest/flint.sh index 49f5e2db8..7cc4f264c 100755 --- a/bin/varnishtest/flint.sh +++ b/bin/varnishtest/flint.sh @@ -4,6 +4,7 @@ FLOPS=' -DTOP_BUILDDIR="foo" -I../../lib/libvgz *.c + teken/teken.c ' . ../../tools/flint_skel.sh diff --git a/bin/varnishtest/gensequences b/bin/varnishtest/gensequences new file mode 100644 index 000000000..83a3d1089 --- /dev/null +++ b/bin/varnishtest/gensequences @@ -0,0 +1,157 @@ +#!/usr/bin/awk -f + +#- +# Copyright (c) 2008-2009 Ed Schouten +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD: head/sys/teken/gensequences 223574 2011-06-26 18:25:10Z ed $ + +function die(msg) { + print msg; + exit 1; +} + +function cchar(str) { + if (str == "^[") + return "\\x1B"; + + return str; +} + +BEGIN { +FS = "\t+" + +while (getline > 0) { + if (NF == 0 || $1 ~ /^#/) + continue; + + if (NF != 3 && NF != 4) + die("Invalid line layout: " NF " columns"); + + split($3, sequence, " +"); + nsequences = 0; + for (s in sequence) + nsequences++; + + prefix = ""; + l_prefix_name[""] = "teken_state_init"; + for (i = 1; i < nsequences; i++) { + n = prefix sequence[i]; + l_prefix_parent[n] = prefix; + l_prefix_suffix[n] = sequence[i]; + if (!l_prefix_name[n]) + l_prefix_name[n] = "teken_state_" ++npr; + prefix = n; + } + + suffix = sequence[nsequences]; + cmd = prefix suffix; + + # Fill lists + if (l_cmd_name[cmd] != "") + die(cmd " already exists"); + l_cmd_prefix[cmd] = prefix; + l_cmd_suffix[cmd] = suffix; + l_cmd_args[cmd] = $4; + l_cmd_abbr[cmd] = $1; + l_cmd_name[cmd] = $2; + l_cmd_c_name[cmd] = "teken_subr_" tolower($2); + gsub(" ", "_", l_cmd_c_name[cmd]); + + if ($4 != "") + l_prefix_numbercmds[prefix]++; +} + +print "/* Generated file. Do not edit. */"; +print ""; + +for (p in l_prefix_name) { + if (l_prefix_name[p] != "teken_state_init") + print "static teken_state_t " l_prefix_name[p] ";"; +} + +for (p in l_prefix_name) { + print ""; + print "/* '" p "' */"; + print "static void"; + print l_prefix_name[p] "(teken_t *t, teken_char_t c)"; + print "{"; + + if (l_prefix_numbercmds[p] > 0) { + print ""; + print "\tif (teken_state_numbers(t, c))"; + print "\t\treturn;"; + } + + print ""; + print "\tswitch (c) {"; + for (c in l_cmd_prefix) { + if (l_cmd_prefix[c] != p) + continue; + + print "\tcase '" cchar(l_cmd_suffix[c]) "': /* " l_cmd_abbr[c] ": " l_cmd_name[c] " */"; + + if (l_cmd_args[c] == "v") { + print "\t\t" l_cmd_c_name[c] "(t, t->t_curnum, t->t_nums);"; + } else { + printf "\t\t%s(t", l_cmd_c_name[c]; + split(l_cmd_args[c], args, " "); + for (a = 1; args[a] != ""; a++) { + if (args[a] == "n") + printf ", (t->t_curnum < %d || t->t_nums[%d] == 0) ? 1 : t->t_nums[%d]", a, (a - 1), (a - 1); + else if (args[a] == "r") + printf ", t->t_curnum < %d ? 0 : t->t_nums[%d]", a, (a - 1); + else + die("Invalid argument type: " args[a]); + } + print ");"; + } + print "\t\tbreak;"; + } + for (pc in l_prefix_parent) { + if (l_prefix_parent[pc] != p) + continue; + print "\tcase '" cchar(l_prefix_suffix[pc]) "':"; + print "\t\tteken_state_switch(t, " l_prefix_name[pc] ");"; + print "\t\treturn;"; + } + + print "\tdefault:"; + if (l_prefix_name[p] == "teken_state_init") { + print "\t\tteken_subr_regular_character(t, c);"; + } else { + print "\t\tteken_printf(\"Unsupported sequence in " l_prefix_name[p] ": %u\\n\", (unsigned int)c);"; + } + print "\t\tbreak;"; + + print "\t}"; + + if (l_prefix_name[p] != "teken_state_init") { + print ""; + print "\tteken_state_switch(t, teken_state_init);"; + } + print "}"; +} + +} diff --git a/bin/varnishtest/sequences b/bin/varnishtest/sequences new file mode 100644 index 000000000..af92df04b --- /dev/null +++ b/bin/varnishtest/sequences @@ -0,0 +1,115 @@ +#- +# Copyright (c) 2008-2009 Ed Schouten +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD: head/sys/teken/sequences 322662 2017-08-18 15:40:40Z bde $ + +# File format is as follows: +# Abbr Abbreviation of sequence name +# Name Sequence name (will be converted to C function name) +# Sequence Bytes that form the sequence +# Arguments Standard value of arguments passed to this sequence +# - `n' non-zero number (0 gets converted to 1) +# - `r' regular numeric argument +# - `v' means a variable number of arguments + +# Abbr Name Sequence Arguments +CBT Cursor Backward Tabulation ^[ [ Z n +CHT Cursor Forward Tabulation ^[ [ I n +CNL Cursor Next Line ^[ [ E n +CPL Cursor Previous Line ^[ [ F n +CPR Cursor Position Report ^[ [ n r +CUB Cursor Backward ^[ [ D n +CUD Cursor Down ^[ [ B n +CUD Cursor Down ^[ [ e n +CUF Cursor Forward ^[ [ C n +CUF Cursor Forward ^[ [ a n +CUP Cursor Position ^[ [ H n n +CUP Cursor Position ^[ [ f n n +CUU Cursor Up ^[ [ A n +DA1 Primary Device Attributes ^[ [ c r +DA2 Secondary Device Attributes ^[ [ > c r +DC Delete character ^[ [ P n +DCS Device Control String ^[ P +DECALN Alignment test ^[ # 8 +DECDHL Double Height Double Width Line Top ^[ # 3 +DECDHL Double Height Double Width Line Bottom ^[ # 4 +DECDWL Single Height Double Width Line ^[ # 6 +DECKPAM Keypad application mode ^[ = +DECKPNM Keypad numeric mode ^[ > +DECRC Restore cursor ^[ 8 +DECRC Restore cursor ^[ [ u +DECRM Reset DEC mode ^[ [ ? l r +DECSC Save cursor ^[ 7 +DECSC Save cursor ^[ [ s +DECSM Set DEC mode ^[ [ ? h r +DECSTBM Set top and bottom margins ^[ [ r r r +DECSWL Single Height Single Width Line ^[ # 5 +DL Delete line ^[ [ M n +DSR Device Status Report ^[ [ ? n r +ECH Erase character ^[ [ X n +ED Erase display ^[ [ J r +EL Erase line ^[ [ K r +G0SCS0 G0 SCS Special Graphics ^[ ( 0 +G0SCS1 G0 SCS US ASCII ^[ ( 1 +G0SCS2 G0 SCS Special Graphics ^[ ( 2 +G0SCSA G0 SCS UK National ^[ ( A +G0SCSB G0 SCS US ASCII ^[ ( B +G1SCS0 G1 SCS Special Graphics ^[ ) 0 +G1SCS1 G1 SCS US ASCII ^[ ) 1 +G1SCS2 G1 SCS Special Graphics ^[ ) 2 +G1SCSA G1 SCS UK National ^[ ) A +G1SCSB G1 SCS US ASCII ^[ ) B +HPA Horizontal Position Absolute ^[ [ G n +HPA Horizontal Position Absolute ^[ [ ` n +HTS Horizontal Tab Set ^[ H +ICH Insert character ^[ [ @ n +IL Insert line ^[ [ L n +IND Index ^[ D +NEL Next line ^[ E +OSC Operating System Command ^[ ] +RI Reverse index ^[ M +RIS Reset to Initial State ^[ c +RM Reset Mode ^[ [ l r +SD Pan Up ^[ [ T n +SGR Set Graphic Rendition ^[ [ m v +SM Set Mode ^[ [ h r +ST String Terminator ^[ \\ +SU Pan Down ^[ [ S n +TBC Tab Clear ^[ [ g r +VPA Vertical Position Absolute ^[ [ d n + +# Cons25 compatibility sequences +C25BLPD Cons25 set bell pitch duration ^[ [ = B r r +C25BORD Cons25 set border ^[ [ = A r +C25DBG Cons25 set default background ^[ [ = G r +C25DFG Cons25 set default foreground ^[ [ = F r +C25GCS Cons25 set global cursor shape ^[ [ = C v +C25LCT Cons25 set local cursor type ^[ [ = S r +C25MODE Cons25 set terminal mode ^[ [ = T r +C25SGR Cons25 set graphic rendition ^[ [ x r r +C25VTSW Cons25 switch virtual terminal ^[ [ z r + +# VT52 compatibility +#DECID VT52 DECID ^[ Z diff --git a/bin/varnishtest/teken.3 b/bin/varnishtest/teken.3 new file mode 100644 index 000000000..c1ece8554 --- /dev/null +++ b/bin/varnishtest/teken.3 @@ -0,0 +1,234 @@ +.\" Copyright (c) 2011 Ed Schouten +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD: head/sys/teken/libteken/teken.3 315418 2017-03-16 16:40:54Z bde $ +.\" +.Dd Mar 13, 2017 +.Dt TEKEN 3 +.Os +.Sh NAME +.Nm teken +.Nd xterm-like terminal emulation interface +.Sh LIBRARY +.Lb libteken +.Sh SYNOPSIS +.In teken.h +.Ft void +.Fn teken_init "teken_t *t" "const teken_funcs_t *funcs" "void *thunk" +.Ft void +.Fn teken_input "teken_t *t" "const void *buf" "size_t nbytes" +.Ft const teken_pos_t * +.Fn teken_get_winsize "teken_t *t" +.Ft void +.Fn teken_set_winsize "teken_t *t" "const teken_pos_t *size" +.Ft const teken_pos_t * +.Fn teken_get_cursor "teken_t *t" +.Ft void +.Fn teken_set_cursor "teken_t *t" "const teken_pos_t *pos" +.Ft const teken_attr_t * +.Fn teken_get_curattr "teken_t *t" +.Ft void +.Fn teken_set_curattr "teken_t *t" "const teken_attr_t *attr" +.Ft const teken_attr_t * +.Fn teken_get_defattr "teken_t *t" +.Ft void +.Fn teken_set_defattr "teken_t *t" "const teken_attr_t *attr" +.Ft const char * +.Fn teken_get_sequence "teken_t *t" "unsigned int id" +.Ft teken_color_t +.Fn teken_256to16 "teken_color_t color" +.Ft teken_color_t +.Fn teken_256to8 "teken_color_t color" +.Ft void +.Fn teken_get_defattr_cons25 "teken_t *t" "int *fg" "int *bg" +.Ft void +.Fn teken_set_8bit "teken_t *t" +.Ft void +.Fn teken_set_cons25 "teken_t *t" +.Sh DESCRIPTION +The +.Nm +library implements the input parser of a 256-color xterm-like terminal. +It converts a stream of UTF-8 encoded characters into a series of +primitive drawing instructions that can be used by a console driver or +terminal emulator to render a terminal application. +.Pp +The +.Fn teken_init +function is used to initialize terminal state object +.Fa t , +having type +.Vt teken_t . +The supplied +.Vt teken_funcs_t +structure +.Fa funcs +contains a set of callback functions, which are called when supplying +data to +.Fn teken_input . +The +.Fa thunk +argument stores an arbitrary pointer, which is passed to each invocation +of the callback functions. +.Pp +The +.Vt teken_funcs_t +structure stores the following callbacks: +.Bd -literal -offset indent +typedef struct { + tf_bell_t *tf_bell; /* Audible/visible bell. */ + tf_cursor_t *tf_cursor; /* Move cursor to x/y. */ + tf_putchar_t *tf_putchar; /* Put Unicode character at x/y. */ + tf_fill_t *tf_fill; /* Fill rectangle with character. */ + tf_copy_t *tf_copy; /* Copy rectangle to new location. */ + tf_param_t *tf_param; /* Miscellaneous options. */ + tf_respond_t *tf_respond; /* Send response string to user. */ +} teken_funcs_t; +.Ed +.Pp +All callbacks must be provided, though unimplemented callbacks may some +times be sufficient. +The actual types of these callbacks can be found in +.In teken.h . +.Pp +By default, +.Fn teken_init +initializes the +.Vt teken_t +structure to emulate a terminal having 24 rows and 80 columns. +The +.Fn teken_get_winsize +and +.Fn teken_set_winsize +functions can be used to obtain and modify the dimensions of the +terminal. +.Pp +Even though the cursor position is normally controlled by input of data +through +.Fn teken_input +and returned by the +.Fn tf_cursor +callback, it can be obtained and modified manually using the +.Fn teken_get_cursor +and +.Fn teken_set_cursor +functions. +The same holds for +.Fn teken_get_curattr +and +.Fn teken_set_curattr , +which can be used to change the currently selected font attributes and +foreground and background color. +.Pp +By default, +.Nm +emulates a white-on-black terminal, which means the default foreground +color is white, while the background color is black. +These defaults can be modified using +.Fn teken_get_defattr +and +.Fn teken_set_defattr . +.Pp +The +.Fn teken_get_sequence +function is a utility function that can be used to obtain escape +sequences of special keyboard keys, generated by user input. +The +.Fa id +parameter must be one of the +.Dv TKEY_* +parameters listed in +.In teken.h . +.Sh LEGACY FEATURES +This library also provides a set of functions that shouldn't be used in +any modern applications. +.Pp +The +.Fn teken_256to16 +function converts an xterm-256 256-color code to an xterm 16-color code +whose color with default palettes is as similar as possible (not very +similar). +The lower 3 bits of the result are the ANSI color and the next lowest +bit is brightness. +Other layers (hardare and software) that only support 16 colors can use +this to avoid knowing the details of 256-color codes. +.Pp +The +.Fn teken_256to8 +function is similar to +.Fn teken_256to16 +except it converts to an ANSI 8-color code. +This is more accurate than discarding the brigtness bit in the result of +.Fn teken_256to16 . +.Pp +The +.Fn teken_get_defattr_cons25 +function obtains the default terminal attributes as a pair of foreground +and background colors, using ANSI color numbering. +.Pp +The +.Fn teken_set_8bit +function disables UTF-8 processing and switches to 8-bit character mode, +which can be used to support character sets like CP437 and ISO-8859-1. +.Pp +The +.Fn teken_set_cons25 +function switches terminal emulation to +.Dv cons25 , +which is used by versions of +.Fx +prior to 9.0. +.Sh SEE ALSO +.Xr ncurses 3 , +.Xr termcap 3 , +.Xr syscons 4 +.Sh HISTORY +The +.Nm +library appeared in +.Fx 8.0 , +though it was only available and used inside the kernel. +In +.Fx 9.0 , +the +.Nm +library appeared in userspace. +.Sh AUTHORS +.An Ed Schouten Aq ed at FreeBSD.org +.Sh SECURITY CONSIDERATIONS +The +.Fn tf_respond +callback is used to respond to device status requests commands generated +by an application. +In the past, there have been various security issues, where a malicious +application sends a device status request before termination, causing +the generated response to be interpreted by applications such as +.Xr sh 1 . +.Pp +.Nm +only implements a small subset of responses which are unlikely to cause +any harm. +Still, it is advised to leave +.Fn tf_respond +unimplemented. diff --git a/bin/varnishtest/teken.c b/bin/varnishtest/teken.c new file mode 100644 index 000000000..8f9076dc6 --- /dev/null +++ b/bin/varnishtest/teken.c @@ -0,0 +1,719 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2008-2009 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/teken/teken.c 326272 2017-11-27 15:23:17Z pfg $ + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "vdef.h" +#include "vas.h" + +#define teken_assert(x) assert(x) + +/* debug messages */ +#define teken_printf(x,...) + +/* Private flags for t_stateflags. */ +#define TS_FIRSTDIGIT 0x0001 /* First numeric digit in escape sequence. */ +#define TS_INSERT 0x0002 /* Insert mode. */ +#define TS_AUTOWRAP 0x0004 /* Autowrap. */ +#define TS_ORIGIN 0x0008 /* Origin mode. */ +#define TS_WRAPPED 0x0010 /* Next character should be printed on col 0. */ +#define TS_8BIT 0x0020 /* UTF-8 disabled. */ +#define TS_CONS25 0x0040 /* cons25 emulation. */ +#define TS_INSTRING 0x0080 /* Inside string. */ +#define TS_CURSORKEYS 0x0100 /* Cursor keys mode. */ + +/* Character that blanks a cell. */ +#define BLANK ' ' + +#include "teken.h" +#include "teken_wcwidth.h" +#include "teken_scs.h" + +static teken_state_t teken_state_init; + +/* + * Wrappers for hooks. + */ + +static inline void +teken_funcs_bell(const teken_t *t) +{ + + if (t->t_funcs->tf_bell != NULL) + t->t_funcs->tf_bell(t->t_softc); +} + +static inline void +teken_funcs_cursor(const teken_t *t) +{ + + teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row); + teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col); + + teken_assert(t->t_funcs->tf_cursor != NULL); + t->t_funcs->tf_cursor(t->t_softc, &t->t_cursor); +} + +static inline void +teken_funcs_putchar(const teken_t *t, const teken_pos_t *p, teken_char_t c, + const teken_attr_t *a) +{ + + teken_assert(p->tp_row < t->t_winsize.tp_row); + teken_assert(p->tp_col < t->t_winsize.tp_col); + + teken_assert(t->t_funcs->tf_putchar != NULL); + t->t_funcs->tf_putchar(t->t_softc, p, c, a); +} + +static inline void +teken_funcs_fill(const teken_t *t, const teken_rect_t *r, + const teken_char_t c, const teken_attr_t *a) +{ + + teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row); + teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row); + teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col); + teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col); + + teken_assert(t->t_funcs->tf_fill != NULL); + t->t_funcs->tf_fill(t->t_softc, r, c, a); +} + +static inline void +teken_funcs_copy(const teken_t *t, const teken_rect_t *r, const teken_pos_t *p) +{ + + teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row); + teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row); + teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col); + teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col); + teken_assert(p->tp_row + (r->tr_end.tp_row - r->tr_begin.tp_row) <= t->t_winsize.tp_row); + teken_assert(p->tp_col + (r->tr_end.tp_col - r->tr_begin.tp_col) <= t->t_winsize.tp_col); + + teken_assert(t->t_funcs->tf_copy != NULL); + t->t_funcs->tf_copy(t->t_softc, r, p); +} + +static inline void +teken_funcs_param(const teken_t *t, int cmd, unsigned int value) +{ + + if (t->t_funcs->tf_param != NULL) + t->t_funcs->tf_param(t->t_softc, cmd, value); +} + +static inline void +teken_funcs_respond(const teken_t *t, const void *buf, size_t len) +{ + + if (t->t_funcs->tf_respond != NULL) + t->t_funcs->tf_respond(t->t_softc, buf, len); +} + +#include "teken_subr.h" +#include "teken_subr_compat.h" + +/* + * Programming interface. + */ + +void +teken_init(teken_t *t, const teken_funcs_t *tf, void *softc) +{ + teken_pos_t tp = { .tp_row = 24, .tp_col = 80 }; + + t->t_funcs = tf; + t->t_softc = softc; + + t->t_nextstate = teken_state_init; + t->t_stateflags = 0; + t->t_utf8_left = 0; + + t->t_defattr.ta_format = 0; + t->t_defattr.ta_fgcolor = TC_WHITE; + t->t_defattr.ta_bgcolor = TC_BLACK; + teken_subr_do_reset(t); + + teken_set_winsize(t, &tp); +} + +static void +teken_input_char(teken_t *t, teken_char_t c) +{ + + /* + * There is no support for DCS and OSC. Just discard strings + * until we receive characters that may indicate string + * termination. + */ + if (t->t_stateflags & TS_INSTRING) { + switch (c) { + case '\x1B': + t->t_stateflags &= ~TS_INSTRING; + break; + case '\a': + t->t_stateflags &= ~TS_INSTRING; + return; + default: + return; + } + } + + switch (c) { + case '\0': + break; + case '\a': + teken_subr_bell(t); + break; + case '\b': + teken_subr_backspace(t); + break; + case '\n': + case '\x0B': + teken_subr_newline(t); + break; + case '\x0C': + teken_subr_newpage(t); + break; + case '\x0E': + if (t->t_stateflags & TS_CONS25) + t->t_nextstate(t, c); + else + t->t_curscs = 1; + break; + case '\x0F': + if (t->t_stateflags & TS_CONS25) + t->t_nextstate(t, c); + else + t->t_curscs = 0; + break; + case '\r': + teken_subr_carriage_return(t); + break; + case '\t': + teken_subr_horizontal_tab(t); + break; + default: + t->t_nextstate(t, c); + break; + } + + /* Post-processing assertions. */ + teken_assert(t->t_cursor.tp_row >= t->t_originreg.ts_begin); + teken_assert(t->t_cursor.tp_row < t->t_originreg.ts_end); + teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row); + teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col); + teken_assert(t->t_saved_cursor.tp_row < t->t_winsize.tp_row); + teken_assert(t->t_saved_cursor.tp_col < t->t_winsize.tp_col); + teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); + teken_assert(t->t_scrollreg.ts_begin < t->t_scrollreg.ts_end); + /* Origin region has to be window size or the same as scrollreg. */ + teken_assert((t->t_originreg.ts_begin == t->t_scrollreg.ts_begin && + t->t_originreg.ts_end == t->t_scrollreg.ts_end) || + (t->t_originreg.ts_begin == 0 && + t->t_originreg.ts_end == t->t_winsize.tp_row)); +} + +static void +teken_input_byte(teken_t *t, unsigned char c) +{ + + /* + * UTF-8 handling. + */ + if ((c & 0x80) == 0x00 || t->t_stateflags & TS_8BIT) { + /* One-byte sequence. */ + t->t_utf8_left = 0; + teken_input_char(t, c); + } else if ((c & 0xe0) == 0xc0) { + /* Two-byte sequence. */ + t->t_utf8_left = 1; + t->t_utf8_partial = c & 0x1f; + } else if ((c & 0xf0) == 0xe0) { + /* Three-byte sequence. */ + t->t_utf8_left = 2; + t->t_utf8_partial = c & 0x0f; + } else if ((c & 0xf8) == 0xf0) { + /* Four-byte sequence. */ + t->t_utf8_left = 3; + t->t_utf8_partial = c & 0x07; + } else if ((c & 0xc0) == 0x80) { + if (t->t_utf8_left == 0) + return; + t->t_utf8_left--; + t->t_utf8_partial = (t->t_utf8_partial << 6) | (c & 0x3f); + if (t->t_utf8_left == 0) { + teken_printf("Got UTF-8 char %x\n", t->t_utf8_partial); + teken_input_char(t, t->t_utf8_partial); + } + } +} + +void +teken_input(teken_t *t, const void *buf, size_t len) +{ + const char *c = buf; + + while (len-- > 0) + teken_input_byte(t, *c++); +} + +const teken_pos_t * +teken_get_cursor(const teken_t *t) +{ + + return (&t->t_cursor); +} + +void +teken_set_cursor(teken_t *t, const teken_pos_t *p) +{ + + /* XXX: bounds checking with originreg! */ + teken_assert(p->tp_row < t->t_winsize.tp_row); + teken_assert(p->tp_col < t->t_winsize.tp_col); + + t->t_cursor = *p; +} + +const teken_attr_t * +teken_get_curattr(const teken_t *t) +{ + + return (&t->t_curattr); +} + +void +teken_set_curattr(teken_t *t, const teken_attr_t *a) +{ + + t->t_curattr = *a; +} + +const teken_attr_t * +teken_get_defattr(const teken_t *t) +{ + + return (&t->t_defattr); +} + +void +teken_set_defattr(teken_t *t, const teken_attr_t *a) +{ + + t->t_curattr = t->t_saved_curattr = t->t_defattr = *a; +} + +const teken_pos_t * +teken_get_winsize(const teken_t *t) +{ + + return (&t->t_winsize); +} + +static void +teken_trim_cursor_pos(teken_t *t, const teken_pos_t *new) +{ + const teken_pos_t *cur; + + cur = &t->t_winsize; + + if (cur->tp_row < new->tp_row || cur->tp_col < new->tp_col) + return; + if (t->t_cursor.tp_row >= new->tp_row) + t->t_cursor.tp_row = new->tp_row - 1; + if (t->t_cursor.tp_col >= new->tp_col) + t->t_cursor.tp_col = new->tp_col - 1; +} + +void +teken_set_winsize(teken_t *t, const teken_pos_t *p) +{ + + teken_trim_cursor_pos(t, p); + t->t_winsize = *p; + teken_subr_do_reset(t); +} + +void +teken_set_winsize_noreset(teken_t *t, const teken_pos_t *p) +{ + + teken_trim_cursor_pos(t, p); + t->t_winsize = *p; + teken_subr_do_resize(t); +} + +void +teken_set_8bit(teken_t *t) +{ + + t->t_stateflags |= TS_8BIT; +} + +void +teken_set_cons25(teken_t *t) +{ + + t->t_stateflags |= TS_CONS25; +} + +/* + * State machine. + */ + +static void +teken_state_switch(teken_t *t, teken_state_t *s) +{ + + t->t_nextstate = s; + t->t_curnum = 0; + t->t_stateflags |= TS_FIRSTDIGIT; +} + +static int +teken_state_numbers(teken_t *t, teken_char_t c) +{ + + teken_assert(t->t_curnum < T_NUMSIZE); + + if (c >= '0' && c <= '9') { + if (t->t_stateflags & TS_FIRSTDIGIT) { + /* First digit. */ + t->t_stateflags &= ~TS_FIRSTDIGIT; + t->t_nums[t->t_curnum] = c - '0'; + } else if (t->t_nums[t->t_curnum] < UINT_MAX / 100) { + /* + * There is no need to continue parsing input + * once the value exceeds the size of the + * terminal. It would only allow for integer + * overflows when performing arithmetic on the + * cursor position. + * + * Ignore any further digits if the value is + * already UINT_MAX / 100. + */ + t->t_nums[t->t_curnum] = + t->t_nums[t->t_curnum] * 10 + c - '0'; + } + return (1); + } else if (c == ';') { + if (t->t_stateflags & TS_FIRSTDIGIT) + t->t_nums[t->t_curnum] = 0; + + /* Only allow a limited set of arguments. */ + if (++t->t_curnum == T_NUMSIZE) { + teken_state_switch(t, teken_state_init); + return (1); + } + + t->t_stateflags |= TS_FIRSTDIGIT; + return (1); + } else { + if (t->t_stateflags & TS_FIRSTDIGIT && t->t_curnum > 0) { + /* Finish off the last empty argument. */ + t->t_nums[t->t_curnum] = 0; + t->t_curnum++; + } else if ((t->t_stateflags & TS_FIRSTDIGIT) == 0) { + /* Also count the last argument. */ + t->t_curnum++; + } + } + + return (0); +} + +#define k TC_BLACK +#define b TC_BLUE +#define y TC_BROWN +#define c TC_CYAN +#define g TC_GREEN +#define m TC_MAGENTA +#define r TC_RED +#define w TC_WHITE +#define K (TC_BLACK | TC_LIGHT) +#define B (TC_BLUE | TC_LIGHT) +#define Y (TC_BROWN | TC_LIGHT) +#define C (TC_CYAN | TC_LIGHT) +#define G (TC_GREEN | TC_LIGHT) +#define M (TC_MAGENTA | TC_LIGHT) +#define R (TC_RED | TC_LIGHT) +#define W (TC_WHITE | TC_LIGHT) + +/** + * The xterm-256 color map has steps of 0x28 (in the range 0-0xff), except + * for the first step which is 0x5f. Scale to the range 0-6 by dividing + * by 0x28 and rounding down. The range of 0-5 cannot represent the + * larger first step. + * + * This table is generated by the follow rules: + * - if all components are equal, the result is black for (0, 0, 0) and + * (2, 2, 2), else white; otherwise: + * - subtract the smallest component from all components + * - if this gives only one nonzero component, then that is the color + * - else if one component is 2 or more larger than the other nonzero one, + * then that component gives the color + * - else there are 2 nonzero components. The color is that of a small + * equal mixture of these components (cyan, yellow or magenta). E.g., + * (0, 5, 6) (Turquoise2) is a much purer cyan than (0, 2, 3) + * (DeepSkyBlue4), but we map both to cyan since we can't represent + * delicate shades of either blue or cyan and blue would be worse. + * Here it is important that components of 1 never occur. Blue would + * be twice as large as green in (0, 1, 2). + */ +static const teken_color_t teken_256to8tab[] = { + /* xterm normal colors: */ + k, r, g, y, b, m, c, w, + + /* xterm bright colors: */ + k, r, g, y, b, m, c, w, + + /* Red0 submap. */ + k, b, b, b, b, b, + g, c, c, b, b, b, + g, c, c, c, b, b, + g, g, c, c, c, b, + g, g, g, c, c, c, + g, g, g, g, c, c, + + /* Red2 submap. */ + r, m, m, b, b, b, + y, k, b, b, b, b, + y, g, c, c, b, b, + g, g, c, c, c, b, + g, g, g, c, c, c, + g, g, g, g, c, c, + + /* Red3 submap. */ + r, m, m, m, b, b, + y, r, m, m, b, b, + y, y, w, b, b, b, + y, y, g, c, c, b, + g, g, g, c, c, c, + g, g, g, g, c, c, + + /* Red4 submap. */ + r, r, m, m, m, b, + r, r, m, m, m, b, + y, y, r, m, m, b, + y, y, y, w, b, b, + y, y, y, g, c, c, + g, g, g, g, c, c, + + /* Red5 submap. */ + r, r, r, m, m, m, + r, r, r, m, m, m, + r, r, r, m, m, m, + y, y, y, r, m, m, + y, y, y, y, w, b, + y, y, y, y, g, c, + + /* Red6 submap. */ + r, r, r, r, m, m, + r, r, r, r, m, m, + r, r, r, r, m, m, + r, r, r, r, m, m, + y, y, y, y, r, m, + y, y, y, y, y, w, + + /* Grey submap. */ + k, k, k, k, k, k, + k, k, k, k, k, k, + w, w, w, w, w, w, + w, w, w, w, w, w, +}; + +/* + * This table is generated from the previous one by setting TC_LIGHT for + * entries whose luminosity in the xterm256 color map is 60% or larger. + * Thus the previous table is currently not really needed. It will be + * used for different fine tuning of the tables. + */ +static const teken_color_t teken_256to16tab[] = { + /* xterm normal colors: */ + k, r, g, y, b, m, c, w, + + /* xterm bright colors: */ + K, R, G, Y, B, M, C, W, + + /* Red0 submap. */ + k, b, b, b, b, b, + g, c, c, b, b, b, + g, c, c, c, b, b, + g, g, c, c, c, b, + g, g, g, c, c, c, + g, g, g, g, c, c, + + /* Red2 submap. */ + r, m, m, b, b, b, + y, K, b, b, B, B, + y, g, c, c, B, B, + g, g, c, c, C, B, + g, G, G, C, C, C, + g, G, G, G, C, C, + + /* Red3 submap. */ + r, m, m, m, b, b, + y, r, m, m, B, B, + y, y, w, B, B, B, + y, y, G, C, C, B, + g, G, G, C, C, C, + g, G, G, G, C, C, + + /* Red4 submap. */ + r, r, m, m, m, b, + r, r, m, m, M, B, + y, y, R, M, M, B, + y, y, Y, W, B, B, + y, Y, Y, G, C, C, + g, G, G, G, C, C, + + /* Red5 submap. */ + r, r, r, m, m, m, + r, R, R, M, M, M, + r, R, R, M, M, M, + y, Y, Y, R, M, M, + y, Y, Y, Y, W, B, + y, Y, Y, Y, G, C, + + /* Red6 submap. */ + r, r, r, r, m, m, + r, R, R, R, M, M, + r, R, R, R, M, M, + r, R, R, R, M, M, + y, Y, Y, Y, R, M, + y, Y, Y, Y, Y, W, + + /* Grey submap. */ + k, k, k, k, k, k, + K, K, K, K, K, K, + w, w, w, w, w, w, + W, W, W, W, W, W, +}; + +#undef k +#undef b +#undef y +#undef c +#undef g +#undef m +#undef r +#undef w +#undef K +#undef B +#undef Y +#undef C +#undef G +#undef M +#undef R +#undef W + +teken_color_t +teken_256to8(teken_color_t c) +{ + + return (teken_256to8tab[c % 256]); +} + +teken_color_t +teken_256to16(teken_color_t c) +{ + + return (teken_256to16tab[c % 256]); +} + +static const char * const special_strings_cons25[] = { + [TKEY_UP] = "\x1B[A", [TKEY_DOWN] = "\x1B[B", + [TKEY_LEFT] = "\x1B[D", [TKEY_RIGHT] = "\x1B[C", + + [TKEY_HOME] = "\x1B[H", [TKEY_END] = "\x1B[F", + [TKEY_INSERT] = "\x1B[L", [TKEY_DELETE] = "\x7F", + [TKEY_PAGE_UP] = "\x1B[I", [TKEY_PAGE_DOWN] = "\x1B[G", + + [TKEY_F1] = "\x1B[M", [TKEY_F2] = "\x1B[N", + [TKEY_F3] = "\x1B[O", [TKEY_F4] = "\x1B[P", + [TKEY_F5] = "\x1B[Q", [TKEY_F6] = "\x1B[R", + [TKEY_F7] = "\x1B[S", [TKEY_F8] = "\x1B[T", + [TKEY_F9] = "\x1B[U", [TKEY_F10] = "\x1B[V", + [TKEY_F11] = "\x1B[W", [TKEY_F12] = "\x1B[X", +}; + +static const char * const special_strings_ckeys[] = { + [TKEY_UP] = "\x1BOA", [TKEY_DOWN] = "\x1BOB", + [TKEY_LEFT] = "\x1BOD", [TKEY_RIGHT] = "\x1BOC", + + [TKEY_HOME] = "\x1BOH", [TKEY_END] = "\x1BOF", +}; + +static const char * const special_strings_normal[] = { + [TKEY_UP] = "\x1B[A", [TKEY_DOWN] = "\x1B[B", + [TKEY_LEFT] = "\x1B[D", [TKEY_RIGHT] = "\x1B[C", + + [TKEY_HOME] = "\x1B[H", [TKEY_END] = "\x1B[F", + [TKEY_INSERT] = "\x1B[2~", [TKEY_DELETE] = "\x1B[3~", + [TKEY_PAGE_UP] = "\x1B[5~", [TKEY_PAGE_DOWN] = "\x1B[6~", + + [TKEY_F1] = "\x1BOP", [TKEY_F2] = "\x1BOQ", + [TKEY_F3] = "\x1BOR", [TKEY_F4] = "\x1BOS", + [TKEY_F5] = "\x1B[15~", [TKEY_F6] = "\x1B[17~", + [TKEY_F7] = "\x1B[18~", [TKEY_F8] = "\x1B[19~", + [TKEY_F9] = "\x1B[20~", [TKEY_F10] = "\x1B[21~", + [TKEY_F11] = "\x1B[23~", [TKEY_F12] = "\x1B[24~", +}; + +const char * +teken_get_sequence(const teken_t *t, unsigned int k) +{ + + /* Cons25 mode. */ + if (t->t_stateflags & TS_CONS25 && + k < sizeof special_strings_cons25 / sizeof(char *)) + return (special_strings_cons25[k]); + + /* Cursor keys mode. */ + if (t->t_stateflags & TS_CURSORKEYS && + k < sizeof special_strings_ckeys / sizeof(char *)) + return (special_strings_ckeys[k]); + + /* Default xterm sequences. */ + if (k < sizeof special_strings_normal / sizeof(char *)) + return (special_strings_normal[k]); + + return (NULL); +} + +#include "teken_state.h" diff --git a/bin/varnishtest/teken.h b/bin/varnishtest/teken.h new file mode 100644 index 000000000..986c3bd36 --- /dev/null +++ b/bin/varnishtest/teken.h @@ -0,0 +1,215 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2008-2009 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/teken/teken.h 326272 2017-11-27 15:23:17Z pfg $ + */ + +#ifndef _TEKEN_H_ +#define _TEKEN_H_ + +#include + +/* + * libteken: terminal emulation library. + * + * This library converts an UTF-8 stream of bytes to terminal drawing + * commands. + */ + +typedef uint32_t teken_char_t; +typedef unsigned short teken_unit_t; +typedef unsigned char teken_format_t; +#define TF_BOLD 0x01 /* Bold character. */ +#define TF_UNDERLINE 0x02 /* Underline character. */ +#define TF_BLINK 0x04 /* Blinking character. */ +#define TF_REVERSE 0x08 /* Reverse rendered character. */ +#define TF_CJK_RIGHT 0x10 /* Right-hand side of CJK character. */ +typedef unsigned char teken_color_t; +#define TC_BLACK 0 +#define TC_RED 1 +#define TC_GREEN 2 +#define TC_BROWN 3 +#define TC_BLUE 4 +#define TC_MAGENTA 5 +#define TC_CYAN 6 +#define TC_WHITE 7 +#define TC_NCOLORS 8 +#define TC_LIGHT 8 /* ORed with the others. */ + +typedef struct { + teken_unit_t tp_row; + teken_unit_t tp_col; +} teken_pos_t; +typedef struct { + teken_pos_t tr_begin; + teken_pos_t tr_end; +} teken_rect_t; +typedef struct { + teken_format_t ta_format; + teken_color_t ta_fgcolor; + teken_color_t ta_bgcolor; +} teken_attr_t; +typedef struct { + teken_unit_t ts_begin; + teken_unit_t ts_end; +} teken_span_t; + +typedef struct __teken teken_t; + +typedef void teken_state_t(teken_t *, teken_char_t); + +/* + * Drawing routines supplied by the user. + */ + +typedef void tf_bell_t(void *); +typedef void tf_cursor_t(void *, const teken_pos_t *); +typedef void tf_putchar_t(void *, const teken_pos_t *, teken_char_t, + const teken_attr_t *); +typedef void tf_fill_t(void *, const teken_rect_t *, teken_char_t, + const teken_attr_t *); +typedef void tf_copy_t(void *, const teken_rect_t *, const teken_pos_t *); +typedef void tf_param_t(void *, int, unsigned int); +#define TP_SHOWCURSOR 0 +#define TP_KEYPADAPP 1 +#define TP_AUTOREPEAT 2 +#define TP_SWITCHVT 3 +#define TP_132COLS 4 +#define TP_SETBELLPD 5 +#define TP_SETBELLPD_PITCH(pd) ((pd) >> 16) +#define TP_SETBELLPD_DURATION(pd) ((pd) & 0xffff) +#define TP_MOUSE 6 +#define TP_SETBORDER 7 +#define TP_SETLOCALCURSOR 8 +#define TP_SETGLOBALCURSOR 9 +typedef void tf_respond_t(void *, const void *, size_t); + +typedef struct { + tf_bell_t *tf_bell; + tf_cursor_t *tf_cursor; + tf_putchar_t *tf_putchar; + tf_fill_t *tf_fill; + tf_copy_t *tf_copy; + tf_param_t *tf_param; + tf_respond_t *tf_respond; +} teken_funcs_t; + +typedef teken_char_t teken_scs_t(const teken_t *, teken_char_t); + +/* + * Terminal state. + */ + +struct __teken { + const teken_funcs_t *t_funcs; + void *t_softc; + + teken_state_t *t_nextstate; + unsigned int t_stateflags; + +#define T_NUMSIZE 8 + unsigned int t_nums[T_NUMSIZE]; + unsigned int t_curnum; + + teken_pos_t t_cursor; + teken_attr_t t_curattr; + teken_pos_t t_saved_cursor; + teken_attr_t t_saved_curattr; + + teken_attr_t t_defattr; + teken_pos_t t_winsize; + + /* For DECSTBM. */ + teken_span_t t_scrollreg; + /* For DECOM. */ + teken_span_t t_originreg; + +#define T_NUMCOL 160 + unsigned int t_tabstops[T_NUMCOL / (sizeof(unsigned int) * 8)]; + + unsigned int t_utf8_left; + teken_char_t t_utf8_partial; + + unsigned int t_curscs; + teken_scs_t *t_saved_curscs; + teken_scs_t *t_scs[2]; +}; + +/* Initialize teken structure. */ +void teken_init(teken_t *, const teken_funcs_t *, void *); + +/* Deliver character input. */ +void teken_input(teken_t *, const void *, size_t); + +/* Get/set teken attributes. */ +const teken_pos_t *teken_get_cursor(const teken_t *); +const teken_attr_t *teken_get_curattr(const teken_t *); +const teken_attr_t *teken_get_defattr(const teken_t *); +void teken_get_defattr_cons25(const teken_t *, int *, int *); +const teken_pos_t *teken_get_winsize(const teken_t *); +void teken_set_cursor(teken_t *, const teken_pos_t *); +void teken_set_curattr(teken_t *, const teken_attr_t *); +void teken_set_defattr(teken_t *, const teken_attr_t *); +void teken_set_winsize(teken_t *, const teken_pos_t *); +void teken_set_winsize_noreset(teken_t *, const teken_pos_t *); + +/* Key input escape sequences. */ +#define TKEY_UP 0x00 +#define TKEY_DOWN 0x01 +#define TKEY_LEFT 0x02 +#define TKEY_RIGHT 0x03 + +#define TKEY_HOME 0x04 +#define TKEY_END 0x05 +#define TKEY_INSERT 0x06 +#define TKEY_DELETE 0x07 +#define TKEY_PAGE_UP 0x08 +#define TKEY_PAGE_DOWN 0x09 + +#define TKEY_F1 0x0a +#define TKEY_F2 0x0b +#define TKEY_F3 0x0c +#define TKEY_F4 0x0d +#define TKEY_F5 0x0e +#define TKEY_F6 0x0f +#define TKEY_F7 0x10 +#define TKEY_F8 0x11 +#define TKEY_F9 0x12 +#define TKEY_F10 0x13 +#define TKEY_F11 0x14 +#define TKEY_F12 0x15 +const char *teken_get_sequence(const teken_t *, unsigned int); + +/* Legacy features. */ +void teken_set_8bit(teken_t *); +void teken_set_cons25(teken_t *); + +/* Color conversion. */ +teken_color_t teken_256to16(teken_color_t); +teken_color_t teken_256to8(teken_color_t); + +#endif /* !_TEKEN_H_ */ diff --git a/bin/varnishtest/teken_scs.h b/bin/varnishtest/teken_scs.h new file mode 100644 index 000000000..fd99de15d --- /dev/null +++ b/bin/varnishtest/teken_scs.h @@ -0,0 +1,83 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2009 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/teken/teken_scs.h 326272 2017-11-27 15:23:17Z pfg $ + */ + +static inline teken_char_t +teken_scs_process(const teken_t *t, teken_char_t c) +{ + + return (t->t_scs[t->t_curscs](t, c)); +} + +/* Unicode points for VT100 box drawing. */ +static const uint16_t teken_boxdrawing_unicode[31] = { + 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, + 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba, + 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c, + 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7 +}; + +/* ASCII points for VT100 box drawing. */ +static const uint8_t teken_boxdrawing_8bit[31] = { + '?', '?', 'H', 'F', 'C', 'L', '?', '?', + 'N', 'V', '+', '+', '+', '+', '+', '-', + '-', '-', '-', '-', '+', '+', '+', '+', + '|', '?', '?', '?', '?', '?', '?', +}; + +static teken_char_t +teken_scs_special_graphics(const teken_t *t, teken_char_t c) +{ + + /* Box drawing. */ + if (c >= '`' && c <= '~') + return (t->t_stateflags & TS_8BIT ? + teken_boxdrawing_8bit[c - '`'] : + teken_boxdrawing_unicode[c - '`']); + return (c); +} + +static teken_char_t +teken_scs_uk_national(const teken_t *t, teken_char_t c) +{ + + /* Pound sign. */ + if (c == '#') + return (t->t_stateflags & TS_8BIT ? 0x9c : 0xa3); + return (c); +} + +static teken_char_t +teken_scs_us_ascii(const teken_t *t, teken_char_t c) +{ + + /* No processing. */ + (void)t; + return (c); +} diff --git a/bin/varnishtest/teken_subr.h b/bin/varnishtest/teken_subr.h new file mode 100644 index 000000000..b67ef5cc0 --- /dev/null +++ b/bin/varnishtest/teken_subr.h @@ -0,0 +1,1315 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2008-2009 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/teken/teken_subr.h 326272 2017-11-27 15:23:17Z pfg $ + */ + +static void teken_subr_cursor_up(teken_t *, unsigned int); +static void teken_subr_erase_line(const teken_t *, unsigned int); +static void teken_subr_regular_character(teken_t *, teken_char_t); +static void teken_subr_reset_to_initial_state(teken_t *); +static void teken_subr_save_cursor(teken_t *); + +static inline int +teken_tab_isset(const teken_t *t, unsigned int col) +{ + unsigned int b, o; + + if (col >= T_NUMCOL) + return ((col % 8) == 0); + + b = col / (sizeof(unsigned int) * 8); + o = col % (sizeof(unsigned int) * 8); + + return (t->t_tabstops[b] & (1U << o)); +} + +static inline void +teken_tab_clear(teken_t *t, unsigned int col) +{ + unsigned int b, o; + + if (col >= T_NUMCOL) + return; + + b = col / (sizeof(unsigned int) * 8); + o = col % (sizeof(unsigned int) * 8); + + t->t_tabstops[b] &= ~(1U << o); +} + +static inline void +teken_tab_set(teken_t *t, unsigned int col) +{ + unsigned int b, o; + + if (col >= T_NUMCOL) + return; + + b = col / (sizeof(unsigned int) * 8); + o = col % (sizeof(unsigned int) * 8); + + t->t_tabstops[b] |= 1U << o; +} + +static void +teken_tab_default(teken_t *t) +{ + unsigned int i; + + memset(t->t_tabstops, 0, T_NUMCOL / 8); + + for (i = 8; i < T_NUMCOL; i += 8) + teken_tab_set(t, i); +} + +static void +teken_subr_do_scroll(const teken_t *t, int amount) +{ + teken_rect_t tr; + teken_pos_t tp; + + teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row); + teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); + teken_assert(amount != 0); + + /* Copy existing data 1 line up. */ + if (amount > 0) { + /* Scroll down. */ + + /* Copy existing data up. */ + if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { + tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount; + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_row = t->t_scrollreg.ts_end; + tr.tr_end.tp_col = t->t_winsize.tp_col; + tp.tp_row = t->t_scrollreg.ts_begin; + tp.tp_col = 0; + teken_funcs_copy(t, &tr, &tp); + + tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount; + } else { + tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; + } + + /* Clear the last lines. */ + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_row = t->t_scrollreg.ts_end; + tr.tr_end.tp_col = t->t_winsize.tp_col; + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); + } else { + /* Scroll up. */ + amount = -amount; + + /* Copy existing data down. */ + if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { + tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount; + tr.tr_end.tp_col = t->t_winsize.tp_col; + tp.tp_row = t->t_scrollreg.ts_begin + amount; + tp.tp_col = 0; + teken_funcs_copy(t, &tr, &tp); + + tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount; + } else { + tr.tr_end.tp_row = t->t_scrollreg.ts_end; + } + + /* Clear the first lines. */ + tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_col = t->t_winsize.tp_col; + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); + } +} + +static ssize_t +teken_subr_do_cpr(const teken_t *t, unsigned int cmd, char response[16]) +{ + + switch (cmd) { + case 5: /* Operating status. */ + strcpy(response, "0n"); + return (2); + case 6: { /* Cursor position. */ + int len; + + len = snprintf(response, 16, "%u;%uR", + (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1, + t->t_cursor.tp_col + 1); + + if (len >= 16) + return (-1); + return (len); + } + case 15: /* Printer status. */ + strcpy(response, "13n"); + return (3); + case 25: /* UDK status. */ + strcpy(response, "20n"); + return (3); + case 26: /* Keyboard status. */ + strcpy(response, "27;1n"); + return (5); + default: + teken_printf("Unknown DSR\n"); + return (-1); + } +} + +static void +teken_subr_alignment_test(teken_t *t) +{ + teken_rect_t tr; + + t->t_cursor.tp_row = t->t_cursor.tp_col = 0; + t->t_scrollreg.ts_begin = 0; + t->t_scrollreg.ts_end = t->t_winsize.tp_row; + t->t_originreg = t->t_scrollreg; + t->t_stateflags &= ~(TS_WRAPPED|TS_ORIGIN); + teken_funcs_cursor(t); + + tr.tr_begin.tp_row = 0; + tr.tr_begin.tp_col = 0; + tr.tr_end = t->t_winsize; + teken_funcs_fill(t, &tr, 'E', &t->t_defattr); +} + +static void +teken_subr_backspace(teken_t *t) +{ + + if (t->t_stateflags & TS_CONS25) { + if (t->t_cursor.tp_col == 0) { + if (t->t_cursor.tp_row == t->t_originreg.ts_begin) + return; + t->t_cursor.tp_row--; + t->t_cursor.tp_col = t->t_winsize.tp_col - 1; + } else { + t->t_cursor.tp_col--; + } + } else { + if (t->t_cursor.tp_col == 0) + return; + + t->t_cursor.tp_col--; + t->t_stateflags &= ~TS_WRAPPED; + } + + teken_funcs_cursor(t); +} + +static void +teken_subr_bell(const teken_t *t) +{ + + teken_funcs_bell(t); +} + +static void +teken_subr_carriage_return(teken_t *t) +{ + + t->t_cursor.tp_col = 0; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_backward(teken_t *t, unsigned int ncols) +{ + + if (ncols > t->t_cursor.tp_col) + t->t_cursor.tp_col = 0; + else + t->t_cursor.tp_col -= ncols; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs) +{ + + do { + /* Stop when we've reached the beginning of the line. */ + if (t->t_cursor.tp_col == 0) + break; + + t->t_cursor.tp_col--; + + /* Tab marker set. */ + if (teken_tab_isset(t, t->t_cursor.tp_col)) + ntabs--; + } while (ntabs > 0); + + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_down(teken_t *t, unsigned int nrows) +{ + + if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) + t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; + else + t->t_cursor.tp_row += nrows; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_forward(teken_t *t, unsigned int ncols) +{ + + if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) + t->t_cursor.tp_col = t->t_winsize.tp_col - 1; + else + t->t_cursor.tp_col += ncols; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs) +{ + + do { + /* Stop when we've reached the end of the line. */ + if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1) + break; + + t->t_cursor.tp_col++; + + /* Tab marker set. */ + if (teken_tab_isset(t, t->t_cursor.tp_col)) + ntabs--; + } while (ntabs > 0); + + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_next_line(teken_t *t, unsigned int ncols) +{ + + t->t_cursor.tp_col = 0; + teken_subr_cursor_down(t, ncols); +} + +static void +teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col) +{ + + row = (row - 1) + t->t_originreg.ts_begin; + t->t_cursor.tp_row = row < t->t_originreg.ts_end ? + row : t->t_originreg.ts_end - 1; + + col--; + t->t_cursor.tp_col = col < t->t_winsize.tp_col ? + col : t->t_winsize.tp_col - 1; + + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_cursor_position_report(const teken_t *t, unsigned int cmd) +{ + char response[18] = "\x1B["; + ssize_t len; + + len = teken_subr_do_cpr(t, cmd, response + 2); + if (len < 0) + return; + + teken_funcs_respond(t, response, len + 2); +} + +static void +teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols) +{ + + t->t_cursor.tp_col = 0; + teken_subr_cursor_up(t, ncols); +} + +static void +teken_subr_cursor_up(teken_t *t, unsigned int nrows) +{ + + if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row) + t->t_cursor.tp_row = t->t_scrollreg.ts_begin; + else + t->t_cursor.tp_row -= nrows; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_delete_character(const teken_t *t, unsigned int ncols) +{ + teken_rect_t tr; + + tr.tr_begin.tp_row = t->t_cursor.tp_row; + tr.tr_end.tp_row = t->t_cursor.tp_row + 1; + tr.tr_end.tp_col = t->t_winsize.tp_col; + + if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { + tr.tr_begin.tp_col = t->t_cursor.tp_col; + } else { + /* Copy characters to the left. */ + tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols; + teken_funcs_copy(t, &tr, &t->t_cursor); + + tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols; + } + + /* Blank trailing columns. */ + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); +} + +static void +teken_subr_delete_line(const teken_t *t, unsigned int nrows) +{ + teken_rect_t tr; + + /* Ignore if outside scrolling region. */ + if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || + t->t_cursor.tp_row >= t->t_scrollreg.ts_end) + return; + + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_row = t->t_scrollreg.ts_end; + tr.tr_end.tp_col = t->t_winsize.tp_col; + + if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { + tr.tr_begin.tp_row = t->t_cursor.tp_row; + } else { + teken_pos_t tp; + + /* Copy rows up. */ + tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows; + tp.tp_row = t->t_cursor.tp_row; + tp.tp_col = 0; + teken_funcs_copy(t, &tr, &tp); + + tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows; + } + + /* Blank trailing rows. */ + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); +} + +static void +teken_subr_device_control_string(teken_t *t) +{ + + teken_printf("Unsupported device control string\n"); + t->t_stateflags |= TS_INSTRING; +} + +static void +teken_subr_device_status_report(const teken_t *t, unsigned int cmd) +{ + char response[19] = "\x1B[?"; + ssize_t len; + + len = teken_subr_do_cpr(t, cmd, response + 3); + if (len < 0) + return; + + teken_funcs_respond(t, response, len + 3); +} + +static void +teken_subr_double_height_double_width_line_top(const teken_t *t) +{ + + (void)t; + teken_printf("double height double width top\n"); +} + +static void +teken_subr_double_height_double_width_line_bottom(const teken_t *t) +{ + + (void)t; + teken_printf("double height double width bottom\n"); +} + +static void +teken_subr_erase_character(const teken_t *t, unsigned int ncols) +{ + teken_rect_t tr; + + tr.tr_begin = t->t_cursor; + tr.tr_end.tp_row = t->t_cursor.tp_row + 1; + + if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) + tr.tr_end.tp_col = t->t_winsize.tp_col; + else + tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; + + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); +} + +static void +teken_subr_erase_display(const teken_t *t, unsigned int mode) +{ + teken_rect_t r; + + r.tr_begin.tp_col = 0; + r.tr_end.tp_col = t->t_winsize.tp_col; + + switch (mode) { + case 1: /* Erase from the top to the cursor. */ + teken_subr_erase_line(t, 1); + + /* Erase lines above. */ + if (t->t_cursor.tp_row == 0) + return; + r.tr_begin.tp_row = 0; + r.tr_end.tp_row = t->t_cursor.tp_row; + break; + case 2: /* Erase entire display. */ + r.tr_begin.tp_row = 0; + r.tr_end.tp_row = t->t_winsize.tp_row; + break; + default: /* Erase from cursor to the bottom. */ + teken_subr_erase_line(t, 0); + + /* Erase lines below. */ + if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) + return; + r.tr_begin.tp_row = t->t_cursor.tp_row + 1; + r.tr_end.tp_row = t->t_winsize.tp_row; + break; + } + + teken_funcs_fill(t, &r, BLANK, &t->t_curattr); +} + +static void +teken_subr_erase_line(const teken_t *t, unsigned int mode) +{ + teken_rect_t r; + + r.tr_begin.tp_row = t->t_cursor.tp_row; + r.tr_end.tp_row = t->t_cursor.tp_row + 1; + + switch (mode) { + case 1: /* Erase from the beginning of the line to the cursor. */ + r.tr_begin.tp_col = 0; + r.tr_end.tp_col = t->t_cursor.tp_col + 1; + break; + case 2: /* Erase entire line. */ + r.tr_begin.tp_col = 0; + r.tr_end.tp_col = t->t_winsize.tp_col; + break; + default: /* Erase from cursor to the end of the line. */ + r.tr_begin.tp_col = t->t_cursor.tp_col; + r.tr_end.tp_col = t->t_winsize.tp_col; + break; + } + + teken_funcs_fill(t, &r, BLANK, &t->t_curattr); +} + +static void +teken_subr_g0_scs_special_graphics(teken_t *t) +{ + + t->t_scs[0] = teken_scs_special_graphics; +} + +static void +teken_subr_g0_scs_uk_national(teken_t *t) +{ + + t->t_scs[0] = teken_scs_uk_national; +} + +static void +teken_subr_g0_scs_us_ascii(teken_t *t) +{ + + t->t_scs[0] = teken_scs_us_ascii; +} + +static void +teken_subr_g1_scs_special_graphics(teken_t *t) +{ + + t->t_scs[1] = teken_scs_special_graphics; +} + +static void +teken_subr_g1_scs_uk_national(teken_t *t) +{ + + t->t_scs[1] = teken_scs_uk_national; +} + +static void +teken_subr_g1_scs_us_ascii(teken_t *t) +{ + + t->t_scs[1] = teken_scs_us_ascii; +} + +static void +teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) +{ + + col--; + t->t_cursor.tp_col = col < t->t_winsize.tp_col ? + col : t->t_winsize.tp_col - 1; + + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_horizontal_tab(teken_t *t) +{ + + teken_subr_cursor_forward_tabulation(t, 1); +} + +static void +teken_subr_horizontal_tab_set(teken_t *t) +{ + + teken_tab_set(t, t->t_cursor.tp_col); +} + +static void +teken_subr_index(teken_t *t) +{ + + if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { + t->t_cursor.tp_row++; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); + } else { + teken_subr_do_scroll(t, 1); + } +} + +static void +teken_subr_insert_character(const teken_t *t, unsigned int ncols) +{ + teken_rect_t tr; + + tr.tr_begin = t->t_cursor; + tr.tr_end.tp_row = t->t_cursor.tp_row + 1; + + if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { + tr.tr_end.tp_col = t->t_winsize.tp_col; + } else { + teken_pos_t tp; + + /* Copy characters to the right. */ + tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; + tp.tp_row = t->t_cursor.tp_row; + tp.tp_col = t->t_cursor.tp_col + ncols; + teken_funcs_copy(t, &tr, &tp); + + tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; + } + + /* Blank current location. */ + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); +} + +static void +teken_subr_insert_line(const teken_t *t, unsigned int nrows) +{ + teken_rect_t tr; + + /* Ignore if outside scrolling region. */ + if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || + t->t_cursor.tp_row >= t->t_scrollreg.ts_end) + return; + + tr.tr_begin.tp_row = t->t_cursor.tp_row; + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_col = t->t_winsize.tp_col; + + if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { + tr.tr_end.tp_row = t->t_scrollreg.ts_end; + } else { + teken_pos_t tp; + + /* Copy lines down. */ + tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; + tp.tp_row = t->t_cursor.tp_row + nrows; + tp.tp_col = 0; + teken_funcs_copy(t, &tr, &tp); + + tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; + } + + /* Blank current location. */ + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); +} + +static void +teken_subr_keypad_application_mode(const teken_t *t) +{ + + teken_funcs_param(t, TP_KEYPADAPP, 1); +} + +static void +teken_subr_keypad_numeric_mode(const teken_t *t) +{ + + teken_funcs_param(t, TP_KEYPADAPP, 0); +} + +static void +teken_subr_newline(teken_t *t) +{ + + t->t_cursor.tp_row++; + + if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { + teken_subr_do_scroll(t, 1); + t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; + } + + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_newpage(teken_t *t) +{ + + if (t->t_stateflags & TS_CONS25) { + teken_rect_t tr; + + /* Clear screen. */ + tr.tr_begin.tp_row = t->t_originreg.ts_begin; + tr.tr_begin.tp_col = 0; + tr.tr_end.tp_row = t->t_originreg.ts_end; + tr.tr_end.tp_col = t->t_winsize.tp_col; + teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); + + /* Cursor at top left. */ + t->t_cursor.tp_row = t->t_originreg.ts_begin; + t->t_cursor.tp_col = 0; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); + } else { + teken_subr_newline(t); + } +} + +static void +teken_subr_next_line(teken_t *t) +{ + + t->t_cursor.tp_col = 0; + teken_subr_newline(t); +} + +static void +teken_subr_operating_system_command(teken_t *t) +{ + + teken_printf("Unsupported operating system command\n"); + t->t_stateflags |= TS_INSTRING; +} + +static void +teken_subr_pan_down(const teken_t *t, unsigned int nrows) +{ + + teken_subr_do_scroll(t, (int)nrows); +} + +static void +teken_subr_pan_up(const teken_t *t, unsigned int nrows) +{ + + teken_subr_do_scroll(t, -(int)nrows); +} + +static void +teken_subr_primary_device_attributes(const teken_t *t, unsigned int request) +{ + + if (request == 0) { + const char response[] = "\x1B[?1;2c"; + + teken_funcs_respond(t, response, sizeof response - 1); + } else { + teken_printf("Unknown DA1\n"); + } +} + +static void +teken_subr_do_putchar(const teken_t *t, const teken_pos_t *tp, teken_char_t c, + int width) +{ + + if (t->t_stateflags & TS_INSERT && + tp->tp_col < t->t_winsize.tp_col - width) { + teken_rect_t ctr; + teken_pos_t ctp; + + /* Insert mode. Move existing characters to the right. */ + ctr.tr_begin = *tp; + ctr.tr_end.tp_row = tp->tp_row + 1; + ctr.tr_end.tp_col = t->t_winsize.tp_col - width; + ctp.tp_row = tp->tp_row; + ctp.tp_col = tp->tp_col + width; + teken_funcs_copy(t, &ctr, &ctp); + } + + teken_funcs_putchar(t, tp, c, &t->t_curattr); + + if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { + teken_pos_t tp2; + teken_attr_t attr; + + /* Print second half of CJK fullwidth character. */ + tp2.tp_row = tp->tp_row; + tp2.tp_col = tp->tp_col + 1; + attr = t->t_curattr; + attr.ta_format |= TF_CJK_RIGHT; + teken_funcs_putchar(t, &tp2, c, &attr); + } +} + +static void +teken_subr_regular_character(teken_t *t, teken_char_t c) +{ + int width; + + if (t->t_stateflags & TS_8BIT) { + if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f)) + return; + c = teken_scs_process(t, c); + width = 1; + } else { + c = teken_scs_process(t, c); + width = teken_wcwidth(c); + /* XXX: Don't process zero-width characters yet. */ + if (width <= 0) + return; + } + + if (t->t_stateflags & TS_CONS25) { + teken_subr_do_putchar(t, &t->t_cursor, c, width); + t->t_cursor.tp_col += width; + + if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { + if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { + /* Perform scrolling. */ + teken_subr_do_scroll(t, 1); + } else { + /* No scrolling needed. */ + if (t->t_cursor.tp_row < + t->t_winsize.tp_row - 1) + t->t_cursor.tp_row++; + } + t->t_cursor.tp_col = 0; + } + } else if (t->t_stateflags & TS_AUTOWRAP && + ((t->t_stateflags & TS_WRAPPED && + t->t_cursor.tp_col + 1 == t->t_winsize.tp_col) || + t->t_cursor.tp_col + width > t->t_winsize.tp_col)) { + teken_pos_t tp; + + /* + * Perform line wrapping, if: + * - Autowrapping is enabled, and + * - We're in the wrapped state at the last column, or + * - The character to be printed does not fit anymore. + */ + if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { + /* Perform scrolling. */ + teken_subr_do_scroll(t, 1); + tp.tp_row = t->t_scrollreg.ts_end - 1; + } else { + /* No scrolling needed. */ + tp.tp_row = t->t_cursor.tp_row + 1; + if (tp.tp_row == t->t_winsize.tp_row) { + /* + * Corner case: regular character + * outside scrolling region, but at the + * bottom of the screen. + */ + teken_subr_do_putchar(t, &t->t_cursor, + c, width); + return; + } + } + + tp.tp_col = 0; + teken_subr_do_putchar(t, &tp, c, width); + + t->t_cursor.tp_row = tp.tp_row; + t->t_cursor.tp_col = width; + t->t_stateflags &= ~TS_WRAPPED; + } else { + /* No line wrapping needed. */ + teken_subr_do_putchar(t, &t->t_cursor, c, width); + t->t_cursor.tp_col += width; + + if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { + t->t_stateflags |= TS_WRAPPED; + t->t_cursor.tp_col = t->t_winsize.tp_col - 1; + } else { + t->t_stateflags &= ~TS_WRAPPED; + } + } + + teken_funcs_cursor(t); +} + +static void +teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) +{ + + switch (cmd) { + case 1: /* Cursor keys mode. */ + t->t_stateflags &= ~TS_CURSORKEYS; + break; + case 2: /* DECANM: ANSI/VT52 mode. */ + teken_printf("DECRST VT52\n"); + break; + case 3: /* 132 column mode. */ + teken_funcs_param(t, TP_132COLS, 0); + teken_subr_reset_to_initial_state(t); + break; + case 5: /* Inverse video. */ + teken_printf("DECRST inverse video\n"); + break; + case 6: /* Origin mode. */ + t->t_stateflags &= ~TS_ORIGIN; + t->t_originreg.ts_begin = 0; + t->t_originreg.ts_end = t->t_winsize.tp_row; + t->t_cursor.tp_row = t->t_cursor.tp_col = 0; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); + break; + case 7: /* Autowrap mode. */ + t->t_stateflags &= ~TS_AUTOWRAP; + break; + case 8: /* Autorepeat mode. */ + teken_funcs_param(t, TP_AUTOREPEAT, 0); + break; + case 25: /* Hide cursor. */ + teken_funcs_param(t, TP_SHOWCURSOR, 0); + break; + case 40: /* Disallow 132 columns. */ + teken_printf("DECRST allow 132\n"); + break; + case 45: /* Disable reverse wraparound. */ + teken_printf("DECRST reverse wraparound\n"); + break; + case 47: /* Switch to alternate buffer. */ + teken_printf("Switch to alternate buffer\n"); + break; + case 1000: /* Mouse input. */ + teken_funcs_param(t, TP_MOUSE, 0); + break; + default: + teken_printf("Unknown DECRST: %u\n", cmd); + } +} + +static void +teken_subr_reset_mode(teken_t *t, unsigned int cmd) +{ + + switch (cmd) { + case 4: + t->t_stateflags &= ~TS_INSERT; + break; + default: + teken_printf("Unknown reset mode: %u\n", cmd); + } +} + +static void +teken_subr_do_resize(teken_t *t) +{ + + t->t_scrollreg.ts_begin = 0; + t->t_scrollreg.ts_end = t->t_winsize.tp_row; + t->t_originreg = t->t_scrollreg; +} + +static void +teken_subr_do_reset(teken_t *t) +{ + + t->t_curattr = t->t_defattr; + t->t_cursor.tp_row = t->t_cursor.tp_col = 0; + t->t_scrollreg.ts_begin = 0; + t->t_scrollreg.ts_end = t->t_winsize.tp_row; + t->t_originreg = t->t_scrollreg; + t->t_stateflags &= TS_8BIT|TS_CONS25; + t->t_stateflags |= TS_AUTOWRAP; + + t->t_scs[0] = teken_scs_us_ascii; + t->t_scs[1] = teken_scs_us_ascii; + t->t_curscs = 0; + + teken_subr_save_cursor(t); + teken_tab_default(t); +} + +static void +teken_subr_reset_to_initial_state(teken_t *t) +{ + + teken_subr_do_reset(t); + teken_subr_erase_display(t, 2); + teken_funcs_param(t, TP_SHOWCURSOR, 1); + teken_funcs_cursor(t); +} + +static void +teken_subr_restore_cursor(teken_t *t) +{ + + t->t_cursor = t->t_saved_cursor; + t->t_curattr = t->t_saved_curattr; + t->t_scs[t->t_curscs] = t->t_saved_curscs; + t->t_stateflags &= ~TS_WRAPPED; + + /* Get out of origin mode when the cursor is moved outside. */ + if (t->t_cursor.tp_row < t->t_originreg.ts_begin || + t->t_cursor.tp_row >= t->t_originreg.ts_end) { + t->t_stateflags &= ~TS_ORIGIN; + t->t_originreg.ts_begin = 0; + t->t_originreg.ts_end = t->t_winsize.tp_row; + } + + teken_funcs_cursor(t); +} + +static void +teken_subr_reverse_index(teken_t *t) +{ + + if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { + t->t_cursor.tp_row--; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); + } else { + teken_subr_do_scroll(t, -1); + } +} + +static void +teken_subr_save_cursor(teken_t *t) +{ + + t->t_saved_cursor = t->t_cursor; + t->t_saved_curattr = t->t_curattr; + t->t_saved_curscs = t->t_scs[t->t_curscs]; +} + +static void +teken_subr_secondary_device_attributes(const teken_t *t, unsigned int request) +{ + + if (request == 0) { + const char response[] = "\x1B[>0;10;0c"; + teken_funcs_respond(t, response, sizeof response - 1); + } else { + teken_printf("Unknown DA2\n"); + } +} + +static void +teken_subr_set_dec_mode(teken_t *t, unsigned int cmd) +{ + + switch (cmd) { + case 1: /* Cursor keys mode. */ + t->t_stateflags |= TS_CURSORKEYS; + break; + case 2: /* DECANM: ANSI/VT52 mode. */ + teken_printf("DECSET VT52\n"); + break; + case 3: /* 132 column mode. */ + teken_funcs_param(t, TP_132COLS, 1); + teken_subr_reset_to_initial_state(t); + break; + case 5: /* Inverse video. */ + teken_printf("DECSET inverse video\n"); + break; + case 6: /* Origin mode. */ + t->t_stateflags |= TS_ORIGIN; + t->t_originreg = t->t_scrollreg; + t->t_cursor.tp_row = t->t_scrollreg.ts_begin; + t->t_cursor.tp_col = 0; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); + break; + case 7: /* Autowrap mode. */ + t->t_stateflags |= TS_AUTOWRAP; + break; + case 8: /* Autorepeat mode. */ + teken_funcs_param(t, TP_AUTOREPEAT, 1); + break; + case 25: /* Display cursor. */ + teken_funcs_param(t, TP_SHOWCURSOR, 1); + break; + case 40: /* Allow 132 columns. */ + teken_printf("DECSET allow 132\n"); + break; + case 45: /* Enable reverse wraparound. */ + teken_printf("DECSET reverse wraparound\n"); + break; + case 47: /* Switch to alternate buffer. */ + teken_printf("Switch away from alternate buffer\n"); + break; + case 1000: /* Mouse input. */ + teken_funcs_param(t, TP_MOUSE, 1); + break; + default: + teken_printf("Unknown DECSET: %u\n", cmd); + } +} + +static void +teken_subr_set_mode(teken_t *t, unsigned int cmd) +{ + + switch (cmd) { + case 4: + teken_printf("Insert mode\n"); + t->t_stateflags |= TS_INSERT; + break; + default: + teken_printf("Unknown set mode: %u\n", cmd); + } +} + +static void +teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, + const unsigned int cmds[]) +{ + unsigned int i, n; + + /* No attributes means reset. */ + if (ncmds == 0) { + t->t_curattr = t->t_defattr; + return; + } + + for (i = 0; i < ncmds; i++) { + n = cmds[i]; + + switch (n) { + case 0: /* Reset. */ + t->t_curattr = t->t_defattr; + break; + case 1: /* Bold. */ + t->t_curattr.ta_format |= TF_BOLD; + break; + case 4: /* Underline. */ + t->t_curattr.ta_format |= TF_UNDERLINE; + break; + case 5: /* Blink. */ + t->t_curattr.ta_format |= TF_BLINK; + break; + case 7: /* Reverse. */ + t->t_curattr.ta_format |= TF_REVERSE; + break; + case 22: /* Remove bold. */ + t->t_curattr.ta_format &= ~TF_BOLD; + break; + case 24: /* Remove underline. */ + t->t_curattr.ta_format &= ~TF_UNDERLINE; + break; + case 25: /* Remove blink. */ + t->t_curattr.ta_format &= ~TF_BLINK; + break; + case 27: /* Remove reverse. */ + t->t_curattr.ta_format &= ~TF_REVERSE; + break; + case 30: /* Set foreground color: black */ + case 31: /* Set foreground color: red */ + case 32: /* Set foreground color: green */ + case 33: /* Set foreground color: brown */ + case 34: /* Set foreground color: blue */ + case 35: /* Set foreground color: magenta */ + case 36: /* Set foreground color: cyan */ + case 37: /* Set foreground color: white */ + t->t_curattr.ta_fgcolor = n - 30; + break; + case 38: /* Set foreground color: 256 color mode */ + if (i + 2 >= ncmds || cmds[i + 1] != 5) + continue; + t->t_curattr.ta_fgcolor = cmds[i + 2]; + i += 2; + break; + case 39: /* Set default foreground color. */ + t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; + break; + case 40: /* Set background color: black */ + case 41: /* Set background color: red */ + case 42: /* Set background color: green */ + case 43: /* Set background color: brown */ + case 44: /* Set background color: blue */ + case 45: /* Set background color: magenta */ + case 46: /* Set background color: cyan */ + case 47: /* Set background color: white */ + t->t_curattr.ta_bgcolor = n - 40; + break; + case 48: /* Set background color: 256 color mode */ + if (i + 2 >= ncmds || cmds[i + 1] != 5) + continue; + t->t_curattr.ta_bgcolor = cmds[i + 2]; + i += 2; + break; + case 49: /* Set default background color. */ + t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; + break; + case 90: /* Set bright foreground color: black */ + case 91: /* Set bright foreground color: red */ + case 92: /* Set bright foreground color: green */ + case 93: /* Set bright foreground color: brown */ + case 94: /* Set bright foreground color: blue */ + case 95: /* Set bright foreground color: magenta */ + case 96: /* Set bright foreground color: cyan */ + case 97: /* Set bright foreground color: white */ + t->t_curattr.ta_fgcolor = (n - 90) + 8; + break; + case 100: /* Set bright background color: black */ + case 101: /* Set bright background color: red */ + case 102: /* Set bright background color: green */ + case 103: /* Set bright background color: brown */ + case 104: /* Set bright background color: blue */ + case 105: /* Set bright background color: magenta */ + case 106: /* Set bright background color: cyan */ + case 107: /* Set bright background color: white */ + t->t_curattr.ta_bgcolor = (n - 100) + 8; + break; + default: + teken_printf("unsupported attribute %u\n", n); + } + } +} + +static void +teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, + unsigned int bottom) +{ + + /* Adjust top row number. */ + if (top > 0) + top--; + /* Adjust bottom row number. */ + if (bottom == 0 || bottom > t->t_winsize.tp_row) + bottom = t->t_winsize.tp_row; + + /* Invalid arguments. */ + if (top >= bottom - 1) { + top = 0; + bottom = t->t_winsize.tp_row; + } + + /* Apply scrolling region. */ + t->t_scrollreg.ts_begin = top; + t->t_scrollreg.ts_end = bottom; + if (t->t_stateflags & TS_ORIGIN) + t->t_originreg = t->t_scrollreg; + + /* Home cursor to the top left of the scrolling region. */ + t->t_cursor.tp_row = t->t_originreg.ts_begin; + t->t_cursor.tp_col = 0; + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} + +static void +teken_subr_single_height_double_width_line(const teken_t *t) +{ + + (void)t; + teken_printf("single height double width???\n"); +} + +static void +teken_subr_single_height_single_width_line(const teken_t *t) +{ + + (void)t; + teken_printf("single height single width???\n"); +} + +static void +teken_subr_string_terminator(const teken_t *t) +{ + + (void)t; + /* + * Strings are already terminated in teken_input_char() when ^[ + * is inserted. + */ +} + +static void +teken_subr_tab_clear(teken_t *t, unsigned int cmd) +{ + + switch (cmd) { + case 0: + teken_tab_clear(t, t->t_cursor.tp_col); + break; + case 3: + memset(t->t_tabstops, 0, T_NUMCOL / 8); + break; + default: + break; + } +} + +static void +teken_subr_vertical_position_absolute(teken_t *t, unsigned int row) +{ + + row = (row - 1) + t->t_originreg.ts_begin; + t->t_cursor.tp_row = row < t->t_originreg.ts_end ? + row : t->t_originreg.ts_end - 1; + + t->t_stateflags &= ~TS_WRAPPED; + teken_funcs_cursor(t); +} diff --git a/bin/varnishtest/teken_subr_compat.h b/bin/varnishtest/teken_subr_compat.h new file mode 100644 index 000000000..9c84f1331 --- /dev/null +++ b/bin/varnishtest/teken_subr_compat.h @@ -0,0 +1,153 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2008-2009 Ed Schouten + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/sys/teken/teken_subr_compat.h 326272 2017-11-27 15:23:17Z pfg $ + */ + +static void +teken_subr_cons25_set_border(const teken_t *t, unsigned int c) +{ + + teken_funcs_param(t, TP_SETBORDER, c); +} + +static void +teken_subr_cons25_set_global_cursor_shape(const teken_t *t, unsigned int ncmds, + const unsigned int cmds[]) +{ + unsigned int code, i; + + /* + * Pack the args to work around API deficiencies. This requires + * knowing too much about the low level to be fully compatible. + * Returning when ncmds > 3 is necessary and happens to be + * compatible. Discarding high bits is necessary and happens to + * be incompatible only for invalid args when ncmds == 3. + */ + if (ncmds > 3) + return; + code = 0; + for (i = ncmds; i > 0; i--) + code = (code << 8) | (cmds[i - 1] & 0xff); + code = (code << 8) | ncmds; + teken_funcs_param(t, TP_SETGLOBALCURSOR, code); +} + +static void +teken_subr_cons25_set_local_cursor_type(const teken_t *t, unsigned int type) +{ + + teken_funcs_param(t, TP_SETLOCALCURSOR, type); +} + +static const teken_color_t cons25_colors[8] = { TC_BLACK, TC_BLUE, + TC_GREEN, TC_CYAN, TC_RED, TC_MAGENTA, TC_BROWN, TC_WHITE }; + +static void +teken_subr_cons25_set_default_background(teken_t *t, unsigned int c) +{ + + t->t_defattr.ta_bgcolor = cons25_colors[c % 8] | (c & 8); + t->t_curattr.ta_bgcolor = cons25_colors[c % 8] | (c & 8); +} + +static void +teken_subr_cons25_set_default_foreground(teken_t *t, unsigned int c) +{ + + t->t_defattr.ta_fgcolor = cons25_colors[c % 8] | (c & 8); + t->t_curattr.ta_fgcolor = cons25_colors[c % 8] | (c & 8); +} + +static const teken_color_t cons25_revcolors[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + +void +teken_get_defattr_cons25(const teken_t *t, int *fg, int *bg) +{ + + *fg = cons25_revcolors[teken_256to8(t->t_defattr.ta_fgcolor)]; + if (t->t_defattr.ta_format & TF_BOLD) + *fg += 8; + *bg = cons25_revcolors[teken_256to8(t->t_defattr.ta_bgcolor)]; +} + +static void +teken_subr_cons25_switch_virtual_terminal(const teken_t *t, unsigned int vt) +{ + + teken_funcs_param(t, TP_SWITCHVT, vt); +} + +static void +teken_subr_cons25_set_bell_pitch_duration(const teken_t *t, unsigned int pitch, + unsigned int duration) +{ + + teken_funcs_param(t, TP_SETBELLPD, (pitch << 16) | + (duration & 0xffff)); +} + +static void +teken_subr_cons25_set_graphic_rendition(teken_t *t, unsigned int cmd, + unsigned int param) +{ + + (void)param; + switch (cmd) { + case 0: /* Reset. */ + t->t_curattr = t->t_defattr; + break; + default: + teken_printf("unsupported attribute %u\n", cmd); + } +} + +static void +teken_subr_cons25_set_terminal_mode(teken_t *t, unsigned int mode) +{ + + switch (mode) { + case 0: /* Switch terminal to xterm. */ + t->t_stateflags &= ~TS_CONS25; + break; + case 1: /* Switch terminal to cons25. */ + t->t_stateflags |= TS_CONS25; + break; + default: + break; + } +} + +#if 0 +static void +teken_subr_vt52_decid(teken_t *t) +{ + const char response[] = "\x1B/Z"; + + teken_funcs_respond(t, response, sizeof response - 1); +} +#endif diff --git a/bin/varnishtest/teken_wcwidth.h b/bin/varnishtest/teken_wcwidth.h new file mode 100644 index 000000000..6482305e1 --- /dev/null +++ b/bin/varnishtest/teken_wcwidth.h @@ -0,0 +1,120 @@ +/* + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + * + * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + * + * $FreeBSD: head/sys/teken/teken_wcwidth.h 186681 2009-01-01 13:26:53Z ed $ + */ + +struct interval { + teken_char_t first; + teken_char_t last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(teken_char_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + +static int teken_wcwidth(teken_char_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ + static const struct interval combining[] = { + { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, + { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, + { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, + { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, + { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, + { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, + { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, + { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, + { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, + { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, + { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, + { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, + { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, + { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, + { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, + { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, + { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, + { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, + { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, + { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, + { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, + { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, + { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, + { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, + { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, + { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, + { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, + { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, + { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, + { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, + { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, + { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, + { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, + { 0xE0100, 0xE01EF } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); +} diff --git a/bin/varnishtest/tests/u00008.vtc b/bin/varnishtest/tests/u00008.vtc index 5b6922bac..8a88ad7aa 100644 --- a/bin/varnishtest/tests/u00008.vtc +++ b/bin/varnishtest/tests/u00008.vtc @@ -36,5 +36,5 @@ process p1 -need-bytes 5000 -screen_dump process p1 -winsz 25 132 -process p1 -need-bytes 7000 -screen_dump -write {q} -wait +process p1 -need-bytes 4000 -screen_dump -write {q} -wait diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 94dbf14ee..6776e88d7 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -135,9 +135,3 @@ void vtc_expect(struct vtclog *, const char *, const char *, const char *, const char *, const char *); void vtc_wait4(struct vtclog *, long, int, int, int); void *vtc_record(struct vtclog *, int, struct vsb *); - -/* vtc_term.c */ -struct term *Term_New(struct vtclog *, int, int); -void Term_Feed(struct term *, const char *, const char *); -void Term_Dump(const struct term *); -void Term_SetSize(struct term *, int, int); diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 7c371036b..fadfb1446 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -54,6 +54,8 @@ #include "vsb.h" #include "vsub.h" +#include "teken.h" + struct process { unsigned magic; #define PROCESS_MAGIC 0x1617b43e @@ -84,14 +86,136 @@ struct process { pthread_t tp; unsigned hasthread; - struct term *term; - int lin; - int col; + int nlin; + int ncol; + char **vram; + teken_t tek[1]; }; static VTAILQ_HEAD(, process) processes = VTAILQ_HEAD_INITIALIZER(processes); +/********************************************************************** + * Terminal emulation + */ + +static void +term_cursor(void *priv, const teken_pos_t *pos) +{ + (void)priv; + (void)pos; +} + +static void +term_putchar(void *priv, const teken_pos_t *pos, teken_char_t ch, + const teken_attr_t *at) +{ + struct process *pp; + + CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC); + (void)at; + if (ch > 126 || ch < 32) + ch = '?'; + assert(pos->tp_row < pp->nlin); + assert(pos->tp_col < pp->ncol); + pp->vram[pos->tp_row][pos->tp_col] = ch; +} + +static void +term_fill(void *priv, const teken_rect_t *r, teken_char_t c, + const teken_attr_t *a) +{ + teken_pos_t p; + + /* Braindead implementation of fill() - just call putchar(). */ + for (p.tp_row = r->tr_begin.tp_row; + p.tp_row < r->tr_end.tp_row; p.tp_row++) + for (p.tp_col = r->tr_begin.tp_col; + p.tp_col < r->tr_end.tp_col; p.tp_col++) + term_putchar(priv, &p, c, a); +} + +static void +term_copy(void *priv, const teken_rect_t *r, const teken_pos_t *p) +{ + struct process *pp; + int nrow, ncol, y; /* Has to be signed - >= 0 comparison */ + + /* + * Copying is a little tricky. We must make sure we do it in + * correct order, to make sure we don't overwrite our own data. + */ + CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC); + + nrow = r->tr_end.tp_row - r->tr_begin.tp_row; + ncol = r->tr_end.tp_col - r->tr_begin.tp_col; + + if (p->tp_row < r->tr_begin.tp_row) { + /* Copy from top to bottom. */ + for (y = 0; y < nrow; y++) + memmove(&pp->vram[p->tp_row + y][p->tp_col], + &pp->vram[r->tr_begin.tp_row + y][r->tr_begin.tp_col], ncol); + } else { + /* Copy from bottom to top. */ + for (y = nrow - 1; y >= 0; y--) + memmove(&pp->vram[p->tp_row + y][p->tp_col], + &pp->vram[r->tr_begin.tp_row + y][r->tr_begin.tp_col], ncol); + } +} + +static const teken_funcs_t process_teken_func = { + .tf_cursor = term_cursor, + .tf_putchar = term_putchar, + .tf_fill = term_fill, + .tf_copy = term_copy, +}; + +static void +term_screen_dump(const struct process *pp) +{ + int i; + + for (i = 0; i < pp->nlin; i++) + vtc_dump(pp->vl, 3, "screen", pp->vram[i], pp->ncol); +} + +static void +term_resize(struct process *pp, int lin, int col) +{ + teken_pos_t pos; + char **vram; + int i, j; + + vram = calloc(lin, sizeof *pp->vram); + AN(vram); + for (i = 0; i < lin; i++) { + vram[i] = malloc(col + 1L); + AN(vram[i]); + memset(vram[i], ' ', col); + vram[i][col] = '\0'; + } + if (pp->vram != NULL) { + for (i = 0; i < lin; i++) { + if (i >= pp->nlin) + break; + j = col; + if (j > pp->ncol) + j = pp->ncol; + memcpy(vram[i], pp->vram[i], j); + } + for (i = 0; i < pp->nlin; i++) + free(pp->vram[i]); + free(pp->vram); + } + pp->vram = vram; + pp->nlin = lin; + pp->ncol = col; + + pos.tp_row = lin; + pos.tp_col = col; + teken_set_winsize(pp->tek, &pos); +} + /********************************************************************** * Allocate and initialize a process */ @@ -131,10 +255,8 @@ process_new(const char *name) p->fd_term = -1; VTAILQ_INSERT_TAIL(&processes, p, list); - p->lin = 25; - p->col = 80; - p->term = Term_New(p->vl, p->lin, p->col); - AN(p->term); + teken_init(p->tek, &process_teken_func, p); + term_resize(p, 25, 80); return (p); } @@ -214,7 +336,7 @@ process_stdout(const struct vev *ev, int what) else if (p->log == 3) vtc_hexdump(p->vl, 4, "stdout", buf, i); (void)write(p->f_stdout, buf, i); - Term_Feed(p->term, buf, buf + i); + teken_input(p->tek, buf, i); return (0); } @@ -311,14 +433,14 @@ process_thread(void *priv) } static void -process_winsz(struct process *p, int fd, int lin, int col) +process_winsz(struct process *p, int fd) { struct winsize ws; int i; memset(&ws, 0, sizeof ws); - ws.ws_row = (short)lin; - ws.ws_col = (short)col; + ws.ws_row = (short)p->nlin; + ws.ws_col = (short)p->ncol; i = ioctl(fd, TIOCSWINSZ, &ws); if (i) vtc_log(p->vl, 4, "TIOCWINSZ %d %s", i, strerror(errno)); @@ -330,7 +452,7 @@ process_init_term(struct process *p, int fd) struct termios tt; int i; - process_winsz(p, fd, p->lin, p->col); + process_winsz(p, fd); memset(&tt, 0, sizeof tt); tt.c_cflag = CREAD | CS8 | HUPCL; @@ -407,7 +529,7 @@ process_start(struct process *p) VSUB_closefrom(STDERR_FILENO + 1); process_init_term(p, slave); - AZ(setenv("TERM", "ansi.sys", 1)); + AZ(setenv("TERM", "xterm", 1)); AZ(unsetenv("TERMCAP")); // Not using NULL because GCC is now even more demented... assert(write(STDERR_FILENO, "+", 1) == 1); @@ -509,6 +631,23 @@ process_write(const struct process *p, const char *text) len, strerror(errno), errno); } +static void +process_write_hex(const struct process *p, const char *text) +{ + struct vsb *vsb; + int j; + + if (!p->hasthread) + vtc_fatal(p->vl, "Cannot write to a non-running process"); + + vsb = vtc_hex_to_bin(p->vl, text); + assert(VSB_len(vsb) >= 0); + vtc_hexdump(p->vl, 4, "sendhex", VSB_data(vsb), VSB_len(vsb)); + j = write(p->fd_term, VSB_data(vsb), VSB_len(vsb)); + assert(j == VSB_len(vsb)); + VSB_destroy(&vsb); +} + static void process_close(struct process *p) { @@ -614,6 +753,7 @@ cmd_process(CMD_ARGS) { struct process *p, *p2; uintmax_t u, v; + unsigned lin,col; (void)priv; (void)cmd; @@ -713,7 +853,7 @@ cmd_process(CMD_ARGS) continue; } if (!strcmp(*av, "-screen_dump")) { - Term_Dump(p->term); + term_screen_dump(p); continue; } if (!strcmp(*av, "-start")) { @@ -730,19 +870,24 @@ cmd_process(CMD_ARGS) continue; } if (!strcmp(*av, "-winsz")) { - p->lin = atoi(av[1]); - assert(p->lin > 1); - p->col = atoi(av[2]); - assert(p->col > 1); + lin = atoi(av[1]); + assert(lin > 1); + col = atoi(av[2]); + assert(col > 1); av += 2; - Term_SetSize(p->term, p->lin, p->col); - process_winsz(p, p->fd_term, p->lin, p->col); + term_resize(p, lin, col); + process_winsz(p, p->fd_term); } if (!strcmp(*av, "-write")) { process_write(p, av[1]); av++; continue; } + if (!strcmp(*av, "-writehex")) { + process_write_hex(p, av[1]); + av++; + continue; + } if (!strcmp(*av, "-writeln")) { process_write(p, av[1]); process_write(p, "\n"); diff --git a/bin/varnishtest/vtc_term.c b/bin/varnishtest/vtc_term.c deleted file mode 100644 index ee9426d76..000000000 --- a/bin/varnishtest/vtc_term.c +++ /dev/null @@ -1,327 +0,0 @@ -/*- - * Copyright (c) 2018 Varnish Software AS - * All rights reserved. - * - * Author: Poul-Henning Kamp - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * A trivial ANSI terminal emulation - */ - -#include "config.h" - -#include -#include -#include - -#include "vtc.h" - -struct term { - unsigned magic; -#define TERM_MAGIC 0x1c258f0f - - struct vtclog *vl; - unsigned state; -#define NTERMARG 10 - int arg[NTERMARG]; - int *argp; - int nlin; - int ncol; - char **vram; - int col; - int line; -}; - -static void -term_clear(char * const *vram, int lin, int col) -{ - int i; - - for (i = 0; i < lin; i++) { - memset(vram[i], ' ', col); - vram[i][col] = '\0'; - } -} - -static void -term_scroll(const struct term *tp) -{ - int i; - char *l; - - l = tp->vram[0]; - for (i = 0; i < tp->nlin -1; i++) - tp->vram[i] = tp->vram[i + 1]; - tp->vram[i] = l; - memset(l, ' ', tp->ncol); -} - -void -Term_Dump(const struct term *tp) -{ - int i; - - for (i = 0; i < tp->nlin; i++) - vtc_dump(tp->vl, 3, "screen", tp->vram[i], tp->ncol); -} - -static void -term_escape(struct term *tp, int c, int n) -{ - int i; - - switch (c) { - case 'A': - // CUU - Cursor up - if (tp->arg[0] == -1) tp->arg[0] = 1; - tp->line -= tp->arg[0]; - if (tp->line < 0) - vtc_fatal(tp->vl, "ANSI A[%d] outside vram", - tp->arg[0]); - break; - case 'B': - // CUD - Cursor down - if (tp->arg[0] == -1) tp->arg[0] = 1; - if (tp->arg[0] > tp->nlin) - vtc_fatal(tp->vl, "ANSI B[%d] outside vram", - tp->arg[0]); - tp->line += tp->arg[0]; - while (tp->line >= tp->nlin) { - term_scroll(tp); - tp->line--; - } - break; - case 'C': - // CUF - Cursor forward - if (tp->arg[0] == -1) tp->arg[0] = 1; - tp->col += tp->arg[0]; - if (tp->col >= tp->ncol) - tp->col = tp->ncol - 1; - break; - case 'D': - // CUB - Cursor backward - if (tp->arg[0] == -1) tp->arg[0] = 1; - tp->col -= tp->arg[0]; - if (tp->col < 0) - tp->col = 0; - break; - case 'h': - // SM - Set Mode (mostly ignored XXX?) - tp->col = 0; - tp->line = 0; - break; - case 'H': - // CUP - Cursor Position - if (tp->arg[0] == -1) tp->arg[0] = 1; - if (tp->arg[1] == -1) tp->arg[1] = 1; - if (tp->arg[0] > tp->nlin || tp->arg[1] > tp->ncol) - vtc_fatal(tp->vl, "ANSI H[%d,%d] outside vram", - tp->arg[0], tp->arg[1]); - tp->line = tp->arg[0] - 1; - tp->col = tp->arg[1] - 1; - break; - case 'J': - // ED - Erase in Display (0=below, 1=above, 2=all) - switch (tp->arg[0]) { - case 2: - term_clear(tp->vram, tp->nlin, tp->ncol); - break; - default: - vtc_fatal(tp->vl, "ANSI J[%d]", tp->arg[0]); - } - break; - case 'K': - // EL - Erase in line (0=right, 1=left, 2=full line) - if (tp->arg[0] == -1) tp->arg[0] = 0; - switch (tp->arg[0]) { - case 0: - for (i = tp->col; i < tp->ncol; i++) - tp->vram[tp->line][i] = ' '; - break; - case 1: - for (i = 0; i < tp->col; i++) - tp->vram[tp->line][i] = ' '; - break; - case 2: - for (i = 0; i < tp->ncol; i++) - tp->vram[tp->line][i] = ' '; - break; - default: - vtc_fatal(tp->vl, "ANSI K[%d]", tp->arg[0]); - } - break; - case 'm': - // SGG - Character Attributes (ignored) - break; - default: - for (i = 0; i < n; i++) - vtc_log(tp->vl, 4, "ANSI arg %d", tp->arg[i]); - vtc_fatal(tp->vl, "ANSI unknown (%c)", c); - break; - } -} - -static void -term_char(struct term *tp, char c) -{ - assert(tp->col < tp->ncol); - assert(tp->line < tp->nlin); - assert(tp->state <= 3); - switch (c) { - case 0x00: - break; - case '\b': - if (tp->col > 0) - tp->col--; - break; - case '\t': - while (++tp->col % 8) - continue; - if (tp->col >= tp->ncol) { - tp->col = 0; - term_char(tp, '\n'); - } - break; - case '\n': - if (tp->line == tp->nlin - 1) - term_scroll(tp); - else - tp->line++; - break; - case '\r': - tp->col = 0; - break; - default: - if (c < ' ' || c > '~') - c = '?'; - tp->vram[tp->line][tp->col++] = c; - if (tp->col >= tp->ncol) { - tp->col = 0; - term_char(tp, '\n'); - } - } -} - -void -Term_Feed(struct term *tp, const char *b, const char *e) -{ - int i; - - while (b < e) { - assert(tp->col < tp->ncol); - assert(tp->line < tp->nlin); - assert(tp->state <= 3); - switch (tp->state) { - case 0: - if (*b == '\x1b') - tp->state = 1; - else if (*(const uint8_t*)b == 0x9b) - tp->state = 2; - else - term_char(tp, *b); - b++; - break; - case 1: - if (*b++ != '[') - vtc_fatal(tp->vl, "ANSI not '[' (0x%x)", - b[-1] & 0xff); - tp->state = 2; - break; - case 2: - tp->argp = tp->arg; - for (i=0; i < NTERMARG; i++) - tp->arg[i] = -1; - tp->state = 3; - if (*b == '?') - b++; - break; - case 3: - if (tp->argp - tp->arg >= NTERMARG) - vtc_fatal(tp->vl, "ANSI too many args"); - - if (isdigit(*b)) { - if (*tp->argp == -1) - *tp->argp = 0; - *tp->argp *= 10; - *tp->argp += *b++ - '0'; - continue; - } - if (*b == ';') { - tp->argp++; - tp->state = 3; - b++; - continue; - } - term_escape(tp, *b++, tp->argp - tp->arg); - tp->state = 0; - break; - default: - WRONG("Wrong ansi state"); - } - } -} - -void -Term_SetSize(struct term *tp, int lin, int col) -{ - char **vram; - int i, j; - - vram = calloc(lin, sizeof *tp->vram); - AN(vram); - for (i = 0; i < lin; i++) { - vram[i] = malloc(col + 1L); - AN(vram[i]); - } - term_clear(vram, lin, col); - if (tp->vram != NULL) { - for (i = 0; i < lin; i++) { - if (i >= tp->nlin) - break; - j = col; - if (j > tp->ncol) - j = tp->ncol; - memcpy(vram[i], tp->vram[i], j); - } - for (i = 0; i < tp->nlin; i++) - free(tp->vram[i]); - free(tp->vram); - } - tp->vram = vram; - tp->nlin = lin; - tp->ncol = col; -} - -struct term * -Term_New(struct vtclog *vl, int lin, int col) -{ - struct term *tp; - - ALLOC_OBJ(tp, TERM_MAGIC); - AN(tp); - tp->vl = vl; - Term_SetSize(tp, lin, col); - tp->line = tp->nlin - 1; - return (tp); -} - From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:33 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:33 +0000 (UTC) Subject: [6.0] 685567af2 Introduce '-expect-text LIN COL PAT' to wait for text somewhere on screen. Message-ID: <20180816085233.E3C7998AC3@lists.varnish-cache.org> commit 685567af24b43486e6a45711e9c8645db7fcc7b4 Author: Poul-Henning Kamp Date: Thu Apr 5 07:28:40 2018 +0000 Introduce '-expect-text LIN COL PAT' to wait for text somewhere on screen. Also reappropriate test a00001 to exercise the Teken code with the vttest (http://invisible-island.net/vttest/) program, if installed. diff --git a/bin/varnishtest/flint.lnt b/bin/varnishtest/flint.lnt index fa51cc85b..78c17a9c7 100644 --- a/bin/varnishtest/flint.lnt +++ b/bin/varnishtest/flint.lnt @@ -1,5 +1,5 @@ -+libh(teken/teken.h) ++libh(teken.h) // Tell FlexeLint when these don't return -function(exit, vtc_fatal) diff --git a/bin/varnishtest/flint.sh b/bin/varnishtest/flint.sh index 7cc4f264c..49f5e2db8 100755 --- a/bin/varnishtest/flint.sh +++ b/bin/varnishtest/flint.sh @@ -4,7 +4,6 @@ FLOPS=' -DTOP_BUILDDIR="foo" -I../../lib/libvgz *.c - teken/teken.c ' . ../../tools/flint_skel.sh diff --git a/bin/varnishtest/tests/a00001.vtc b/bin/varnishtest/tests/a00001.vtc index e15969e2e..1dd3f3634 100644 --- a/bin/varnishtest/tests/a00001.vtc +++ b/bin/varnishtest/tests/a00001.vtc @@ -1,26 +1,44 @@ -# the first token in a varnishtest file must be "varnishtest", - # but whitespace (SP) - # and (TAB) and comments are fine -varnishtest "basic default HTTP transactions with expect" - -server s1 { - rxreq - expect req.method == GET - expect req.proto == HTTP/1.1 - expect req.url == "/" - txresp -} - -server s1 -start - -client c1 -connect ${s1_sock} { - txreq - rxresp - expect resp.proto == HTTP/1.1 - expect resp.status == 200 - expect resp.reason == OK -} - -client c1 -run - -server s1 -wait +varnishtest "Test Teken terminal emulator" + +feature cmd "vttest --version 2>&1 | grep -q Usage" + +process p4 -dump {vttest} -start + +process p4 -expect-text 21 11 "Enter choice number (0 - 12):" +process p4 -screen_dump + +process p4 -writehex "31 0d" +process p4 -expect-text 14 61 "RETURN" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 14 87 "RETURN" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 22 7 "RETURN" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 3 132 "i" +process p4 -expect-text 22 7 "RETURN" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 9 7 "RETURN" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 4 1 "This is a correct sentence" +process p4 -expect-text 20 7 "RETURN" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 21 11 "Enter choice number (0 - 12):" +process p4 -screen_dump + +process p4 -writehex "30 0d" +process p4 -expect-text 12 30 "That's all, folks!" +process p4 -screen_dump + +process p4 -wait diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index fadfb1446..0dbe46fc0 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -95,6 +95,8 @@ struct process { static VTAILQ_HEAD(, process) processes = VTAILQ_HEAD_INITIALIZER(processes); +static void term_resize(struct process *pp, int lin, int col); + /********************************************************************** * Terminal emulation */ @@ -163,11 +165,40 @@ term_copy(void *priv, const teken_rect_t *r, const teken_pos_t *p) } } +static void +term_respond(void *priv, const void *p, size_t l) +{ + struct process *pp; + int r; + + CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC); + + vtc_dump(pp->vl, 4, "term_response", p, l); + r = write(pp->fd_term, p, l); + if (r != l) + vtc_fatal(pp->vl, "Could not write to process: %s", + strerror(errno)); +} + +static void +term_param(void *priv, int p, unsigned int v) +{ + struct process *pp; + + CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC); + if (p == TP_132COLS && v) + term_resize(pp, pp->nlin, 132); + if (p == TP_132COLS && !v) + term_resize(pp, pp->nlin, 80); +} + static const teken_funcs_t process_teken_func = { .tf_cursor = term_cursor, .tf_putchar = term_putchar, .tf_fill = term_fill, .tf_copy = term_copy, + .tf_respond = term_respond, + .tf_param = term_param, }; static void @@ -216,6 +247,69 @@ term_resize(struct process *pp, int lin, int col) teken_set_winsize(pp->tek, &pos); } +static int +term_match_textline(const struct process *pp, int *x, int y, const char *pat) +{ + const char *t; + + if (*x == 0) { + t = strstr(pp->vram[y], pat); + if (t != NULL) { + *x = 1 + (t - pp->vram[y]); + return (1); + } + } else if (*x <= pp->ncol) { + t = pp->vram[y] + *x - 1; + if (!memcmp(t, pat, strlen(pat))) + return (1); + } + return (0); +} + +static int +term_match_text(const struct process *pp, int *x, int *y, const char *pat) +{ + int yy; + + if (*y == 0) { + for (yy = 0; yy < pp->nlin; yy++) { + if (term_match_textline(pp, x, yy, pat)) { + *y = yy + 1; + return (1); + } + } + } else if (*y <= pp->nlin) { + if (term_match_textline(pp, x, *y - 1, pat)) + return (1); + } + return (0); +} + +static void +term_expect_text(struct process *pp, + const char *lin, const char *col, const char *pat) +{ + int x, y, l; + char *t; + + y = strtoul(lin, NULL, 0); + x = strtoul(col, NULL, 0); + l = strlen(pat); + AZ(pthread_mutex_lock(&pp->mtx)); + while (!term_match_text(pp, &x, &y, pat)) { + if (x != 0 && y != 0) { + t = pp->vram[y - 1] + x - 1; + vtc_log(pp->vl, 4, + "text at %d,%d: '%.*s'", y, x, l, t); + } + AZ(pthread_mutex_unlock(&pp->mtx)); + usleep(1000000); + AZ(pthread_mutex_lock(&pp->mtx)); + } + AZ(pthread_mutex_unlock(&pp->mtx)); + vtc_log(pp->vl, 4, "found expected text at %d,%d: '%s'", y, x, pat); +} + /********************************************************************** * Allocate and initialize a process */ @@ -256,7 +350,7 @@ process_new(const char *name) VTAILQ_INSERT_TAIL(&processes, p, list); teken_init(p->tek, &process_teken_func, p); - term_resize(p, 25, 80); + term_resize(p, 24, 80); return (p); } @@ -336,7 +430,9 @@ process_stdout(const struct vev *ev, int what) else if (p->log == 3) vtc_hexdump(p->vl, 4, "stdout", buf, i); (void)write(p->f_stdout, buf, i); + AZ(pthread_mutex_lock(&p->mtx)); teken_input(p->tek, buf, i); + AZ(pthread_mutex_unlock(&p->mtx)); return (0); } @@ -740,6 +836,15 @@ process_close(struct process *p) * \-writeln STRING * Same as -write followed by a newline (\\n). * + * \-writehex HEXSTRING + * Same as -write but interpreted as hexadecimal bytes. + * + * \-expect-text LIN COL PAT + * Wait for PAT to appear at LIN,COL on the virtual screen. + * Lines and columns are numbered 1...N + * LIN==0 means "on any line" + * COL==0 means "anywhere on the line" + * * \-close * Alias for "-kill HUP" * @@ -852,6 +957,14 @@ cmd_process(CMD_ARGS) process_wait(p); continue; } + if (!strcmp(*av, "-expect-text")) { + AN(av[1]); + AN(av[2]); + AN(av[3]); + term_expect_text(p, av[1], av[2], av[3]); + av += 3; + continue; + } if (!strcmp(*av, "-screen_dump")) { term_screen_dump(p); continue; @@ -875,7 +988,9 @@ cmd_process(CMD_ARGS) col = atoi(av[2]); assert(col > 1); av += 2; + AZ(pthread_mutex_lock(&p->mtx)); term_resize(p, lin, col); + AZ(pthread_mutex_unlock(&p->mtx)); process_winsz(p, p->fd_term); } if (!strcmp(*av, "-write")) { From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:34 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:34 +0000 (UTC) Subject: [6.0] 06aa55077 Remove the "feature term" test now that we use TERM=xterm Message-ID: <20180816085234.43CEC98AE6@lists.varnish-cache.org> commit 06aa55077fabaac57ff2db96b079d523c56b6103 Author: Poul-Henning Kamp Date: Thu Apr 5 07:32:41 2018 +0000 Remove the "feature term" test now that we use TERM=xterm diff --git a/bin/varnishtest/tests/u00008.vtc b/bin/varnishtest/tests/u00008.vtc index 8a88ad7aa..052a1c951 100644 --- a/bin/varnishtest/tests/u00008.vtc +++ b/bin/varnishtest/tests/u00008.vtc @@ -1,7 +1,5 @@ varnishtest "trivial run of varnistat in curses mode" -feature term - server s1 -repeat 4 { rxreq txresp diff --git a/bin/varnishtest/tests/u00009.vtc b/bin/varnishtest/tests/u00009.vtc index 89e6ea7fd..5825179e8 100644 --- a/bin/varnishtest/tests/u00009.vtc +++ b/bin/varnishtest/tests/u00009.vtc @@ -1,7 +1,5 @@ varnishtest "trivial run of varnishhist in curses mode" -feature term - server s1 { rxreq txresp diff --git a/bin/varnishtest/tests/u00010.vtc b/bin/varnishtest/tests/u00010.vtc index a143c720a..009199dfa 100644 --- a/bin/varnishtest/tests/u00010.vtc +++ b/bin/varnishtest/tests/u00010.vtc @@ -1,7 +1,5 @@ varnishtest "trivial run of varnishtop in curses mode" -feature term - server s1 { rxreq txresp diff --git a/bin/varnishtest/tests/u00011.vtc b/bin/varnishtest/tests/u00011.vtc index 90fcfe2c9..c1a60086e 100644 --- a/bin/varnishtest/tests/u00011.vtc +++ b/bin/varnishtest/tests/u00011.vtc @@ -1,7 +1,5 @@ varnishtest "trivial run of varnishadm in curses mode" -feature term - server s1 { rxreq txresp diff --git a/bin/varnishtest/tests/u00012.vtc b/bin/varnishtest/tests/u00012.vtc index 0660d0741..5fb9b3520 100644 --- a/bin/varnishtest/tests/u00012.vtc +++ b/bin/varnishtest/tests/u00012.vtc @@ -1,7 +1,5 @@ varnishtest "trivial run of varnishadm in pass mode" -feature term - server s1 { rxreq txresp diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c index 06b01676c..8ffe69643 100644 --- a/bin/varnishtest/vtc_misc.c +++ b/bin/varnishtest/vtc_misc.c @@ -341,8 +341,6 @@ cmd_delay(CMD_ARGS) * ignore_unknown_macro * Do not fail the test if a string of the form ${...} is not * recognized as a macro. - * term - * Support for ansi.sys terminal * * persistent_storage * Varnish was built with the deprecated persistent storage. @@ -358,23 +356,6 @@ static const unsigned with_persistent_storage = 1; static const unsigned with_persistent_storage = 0; #endif -static int -test_term(struct vtclog *vl) -{ - FILE *p; - int a, b; - - p = popen("tput -T ansi.sys clear 2>&1", "r"); - if (p == NULL) - return (0); - a = fgetc(p); - b = fgetc(p); - if (a == 0x1b && b == '[') - return (1); - vtc_log(vl, 3, "No 'ansi.sys' terminfo entry."); - return (0); -} - void v_matchproto_(cmd_f) cmd_feature(CMD_ARGS) { @@ -423,7 +404,6 @@ cmd_feature(CMD_ARGS) FEATURE("user_varnish", getpwnam("varnish") != NULL); FEATURE("user_vcache", getpwnam("vcache") != NULL); FEATURE("group_varnish", getgrnam("varnish") != NULL); - FEATURE("term", test_term(vl)); FEATURE("persistent_storage", with_persistent_storage); if (!strcmp(*av, "disable_aslr")) { From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:34 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:34 +0000 (UTC) Subject: [6.0] 9980a67d6 umem: suncc happyness, set fptrs NULL in mgmt Message-ID: <20180816085234.78DF098B0C@lists.varnish-cache.org> commit 9980a67d611ac58d798c137948f6634ee0b655db Author: Nils Goroll Date: Thu Apr 5 10:52:16 2018 +0200 umem: suncc happyness, set fptrs NULL in mgmt diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c index db8178ab8..e36693974 100644 --- a/bin/varnishd/storage/storage_umem.c +++ b/bin/varnishd/storage/storage_umem.c @@ -329,9 +329,11 @@ smu_init(struct stevedore *parent, int ac, char * const *av) #define DLSYM_UMEM(fptr,sym) \ do { \ (void) dlerror(); \ - if ((fptr = dlsym(libumem_hndl, #sym)) == NULL) \ - ARGV_ERR("(-sumem) cannot find symbol " #sym ": %s", \ - dlerror()); \ + if (dlsym(libumem_hndl, #sym) == NULL) \ + ARGV_ERR("(-sumem) cannot find symbol " \ + #sym ": %s", \ + dlerror()); \ + fptr = NULL; \ } while(0) DLSYM_UMEM(umem_allocf, umem_alloc); @@ -372,7 +374,7 @@ smu_open_init(void) #define DLSYM_UMEM(fptr,sym) \ do { \ - fptr = dlsym(libumem_hndl, #sym); \ + fptr = (sym ## _f) dlsym(libumem_hndl, #sym); \ AN(fptr); \ } while(0) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:34 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:34 +0000 (UTC) Subject: [6.0] 173da8481 suncc happyness Message-ID: <20180816085234.9DD3698B25@lists.varnish-cache.org> commit 173da8481cfba0b9ae7eb081324003fc444b97bd Author: Nils Goroll Date: Thu Apr 5 10:58:40 2018 +0200 suncc happyness diff --git a/bin/varnishtest/teken.c b/bin/varnishtest/teken.c index 8f9076dc6..ad06c57c6 100644 --- a/bin/varnishtest/teken.c +++ b/bin/varnishtest/teken.c @@ -42,7 +42,7 @@ #define teken_assert(x) assert(x) /* debug messages */ -#define teken_printf(x,...) +#define teken_printf(...) /* Private flags for t_stateflags. */ #define TS_FIRSTDIGIT 0x0001 /* First numeric digit in escape sequence. */ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:34 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:34 +0000 (UTC) Subject: [6.0] fd4b7ba1f Replace N-1 -need-bytes with -expect-text for better test stability. Message-ID: <20180816085234.C41A098B31@lists.varnish-cache.org> commit fd4b7ba1f6acd50b18f37ba0f6749bb3dae9dbee Author: Poul-Henning Kamp Date: Thu Apr 5 09:54:11 2018 +0000 Replace N-1 -need-bytes with -expect-text for better test stability. Last -need-bytes kept to test that it still works. diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index fe5682dbf..affa7472c 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -47,9 +47,9 @@ process p2 "stty -a ; sleep 1" -run -screen_dump process p3 "stty raw -echo ; stty -a ; sleep 1" -run -screen_dump -process p4 -hexdump {stty raw -echo; echo "*" ; cat} -start +process p4 -hexdump {stty raw -echo; echo "*" ; sleep 2 ; cat} -start -process p4 -need-bytes 2 +process p4 -expect-text 0 0 "*" process p4 -write "\x1b[H\x1b[2J1\x1b[79C2\x08>\x1b[25;1H3\x1b[25;80H" process p4 -write "4\x08>\x1b[A\x1b[Cv\x1b[22A^\x1b[79D^\x1b[;2H<\n\n\n\n" @@ -60,4 +60,5 @@ process p4 -write "333\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" process p4 -write ";12H\x1b[K\x1b[13;12H\x1b[0K\x1b[14;12H\x1b[1K\x1b" process p4 -write "[15;12H\x1b[2K\x1b[3;1Hline3 <\x0d\x0a" -process p4 -need-bytes 252 -screen_dump -stop +process p4 -need-bytes 252 -expect-text 3 1 "line3 <" +process p4 -screen_dump -stop diff --git a/bin/varnishtest/tests/u00000.vtc b/bin/varnishtest/tests/u00000.vtc index fe5b79863..7e426ec96 100644 --- a/bin/varnishtest/tests/u00000.vtc +++ b/bin/varnishtest/tests/u00000.vtc @@ -2,7 +2,7 @@ varnishtest "Simple process tests" process p1 "cat" -start process p1 -writeln "foo" -process p1 -need-bytes 3 +process p1 -expect-text 2 1 foo process p1 -stop process p1 -wait shell "grep -q foo ${p1_out}" @@ -10,7 +10,7 @@ shell "test -f ${p1_err} -a ! -s ${p1_err}" process p2 -log "cat" -start process p2 -writeln "bar" -process p2 -need-bytes 3 +process p2 -expect-text 2 1 bar process p2 -write "\x04" process p2 -wait shell "grep -q bar ${p2_out}" @@ -18,7 +18,7 @@ shell "test -f ${p2_err} -a ! -s ${p2_err}" process p3 -dump "cat" -start process p3 -writeln "baz" -process p3 -need-bytes 3 +process p3 -expect-text 2 1 baz process p3 -kill KILL process p3 -wait shell "grep -q baz ${p3_out}" @@ -26,7 +26,7 @@ shell "test -f ${p3_err} -a ! -s ${p3_err}" process p4 -hexdump "cat" -start process p4 -writeln "b\001z" -process p4 -need-bytes 3 +process p4 -expect-text 2 1 "b" process p4 -kill TERM process p4 -wait -screen_dump diff --git a/bin/varnishtest/tests/u00008.vtc b/bin/varnishtest/tests/u00008.vtc index 052a1c951..5e1beff3e 100644 --- a/bin/varnishtest/tests/u00008.vtc +++ b/bin/varnishtest/tests/u00008.vtc @@ -13,26 +13,33 @@ varnish v1 -vcl+backend { process p1 -dump {varnishstat -n ${v1_name}} -start -process p1 -need-bytes 1 +process p1 -expect-text 0 0 "VBE.vcl1.s1.happy" +process p1 -screen_dump client c1 { txreq rxresp } -run -process p1 -need-bytes 1000 +process p1 -expect-text 0 0 "MAIN.s_sess" +process p1 -screen_dump process p1 -write {vG} +process p1 -expect-text 0 0 "VBE.vcl1.s1.req" +process p1 -expect-text 0 0 "DIAG" +process p1 -screen_dump varnish v1 -stop +process p1 -expect-text 2 1 "Uptime child: Not Running" +process p1 -screen_dump process p1 -write {dek} - -delay 1 - -process p1 -need-bytes 5000 -screen_dump +process p1 -expect-text 0 1 "Concurrent connections to backend:" +process p1 -screen_dump process p1 -winsz 25 132 +process p1 -expect-text 4 124 "AVG_1000" +process p1 -expect-text 22 108 "UNSEEN DIAG" -process p1 -need-bytes 4000 -screen_dump -write {q} -wait +process p1 -screen_dump -write {q} -wait diff --git a/bin/varnishtest/tests/u00009.vtc b/bin/varnishtest/tests/u00009.vtc index 5825179e8..eb587bcbe 100644 --- a/bin/varnishtest/tests/u00009.vtc +++ b/bin/varnishtest/tests/u00009.vtc @@ -9,11 +9,13 @@ varnish v1 -vcl+backend {} -start process p1 -dump {varnishhist -n ${v1_name}} -start -process p1 -need-bytes 1 +process p1 -expect-text 0 0 {1e2} client c1 { txreq rxresp } -run -process p1 -need-bytes 200 -screen_dump -write {q} -wait +process p1 -expect-text 0 0 {#} + +process p1 -screen_dump -write {q} -wait diff --git a/bin/varnishtest/tests/u00010.vtc b/bin/varnishtest/tests/u00010.vtc index 009199dfa..9104c489b 100644 --- a/bin/varnishtest/tests/u00010.vtc +++ b/bin/varnishtest/tests/u00010.vtc @@ -9,11 +9,12 @@ varnish v1 -vcl+backend {} -start process p1 -dump {varnishtop -n ${v1_name}} -start -process p1 -need-bytes 1 +process p1 -expect-text 1 1 {list length} client c1 { txreq rxresp } -run -process p1 -need-bytes 500 -screen_dump -write {q} -wait +process p1 -expect-text 0 0 {Fetch_Body} +process p1 -screen_dump -write {q} -wait diff --git a/bin/varnishtest/tests/u00011.vtc b/bin/varnishtest/tests/u00011.vtc index c1a60086e..d6e8098dd 100644 --- a/bin/varnishtest/tests/u00011.vtc +++ b/bin/varnishtest/tests/u00011.vtc @@ -16,18 +16,18 @@ varnish v1 -vsl_catchup process p1 -log {varnishadm -n ${v1_name}} -start -process p1 -need-bytes 1 +process p1 -expect-text 0 1 "Type 'quit' to close CLI session." process p1 -write "pi\t\r" -process p1 -need-bytes 100 +process p1 -expect-text 0 1 "PONG" process p1 -write "vcl.li\t\r" -process p1 -need-bytes 200 +process p1 -expect-text 0 1 "active auto/warm" process p1 -write "vcl.s\t\th\tvcl1\r" -process p1 -need-bytes 590 +process p1 -expect-text 0 1 "backend s1" process p1 -screen_dump -write "quit\r" -wait diff --git a/bin/varnishtest/tests/u00012.vtc b/bin/varnishtest/tests/u00012.vtc index 5fb9b3520..e9822213a 100644 --- a/bin/varnishtest/tests/u00012.vtc +++ b/bin/varnishtest/tests/u00012.vtc @@ -18,14 +18,14 @@ process p1 -log {cat | varnishadm -n ${v1_name}} -start process p1 -write "ping\r" -process p1 -need-bytes 30 +process p1 -expect-text 0 1 "PONG" process p1 -write "vcl.list\r" -process p1 -need-bytes 80 +process p1 -expect-text 0 0 "auto/warm" process p1 -write "vcl.show vcl1\r" -process p1 -need-bytes 100 +process p1 -expect-text 0 0 "backend s1" process p1 -screen_dump -write "\x04" -wait From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:34 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:34 +0000 (UTC) Subject: [6.0] 8b2a95615 Sync Message-ID: <20180816085235.0019898B48@lists.varnish-cache.org> commit 8b2a95615007eb5330c46b90c9cf68a25cdf7be4 Author: Federico G. Schwindt Date: Thu Apr 5 11:00:34 2018 +0100 Sync diff --git a/.gitignore b/.gitignore index 2453bd5a1..74f73ae61 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,7 @@ cscope.*out /bin/varnishncsa/varnishncsa /bin/varnishstat/varnishstat /bin/varnishstat/vsc2rst +/bin/varnishtest/teken_state.h /bin/varnishtest/varnishtest /bin/varnishtop/varnishtop From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:35 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:35 +0000 (UTC) Subject: [6.0] fe3cef561 Rework to avoid running the tests twice Message-ID: <20180816085235.3DDBC98B5A@lists.varnish-cache.org> commit fe3cef56158d26b4d6cfd6e22d7232c084c0e514 Author: Federico G. Schwindt Date: Thu Apr 5 11:00:48 2018 +0100 Rework to avoid running the tests twice diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 06f2259fe..392b02a13 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -77,11 +77,10 @@ EXTRA_DIST = $(top_srcdir)/bin/varnishtest/tests/*.vtc \ $(top_srcdir)/bin/varnishtest/sequences \ $(top_srcdir)/bin/varnishtest/teken.3 +teken.c: teken_state.h + teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences awk -f $(srcdir)/gensequences $(srcdir)/sequences \ > $(builddir)/teken_state.h -BUILT_SOURCES = teken_state.h - -CLEANFILES = $(BUILT_SOURCES) - +CLEANFILES = $(builddir)/teken_state.h From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:35 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:35 +0000 (UTC) Subject: [6.0] dae345078 Correct path Message-ID: <20180816085235.718EB98B6E@lists.varnish-cache.org> commit dae34507847a9caaa5c7495703e7eb5017afc261 Author: Federico G. Schwindt Date: Thu Apr 5 11:01:01 2018 +0100 Correct path diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index 2d556a78e..b7d81d459 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -737,7 +737,7 @@ vcc_Var_Init(struct vcc *tl) """) -parse_var_doc(join(buildroot, "doc/sphinx/reference/vcl_var.rst")) +parse_var_doc(join(srcroot, "doc/sphinx/reference/vcl_var.rst")) fo.write("}\n") for i in stv_variables: From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:35 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:35 +0000 (UTC) Subject: [6.0] ca9fda642 flexelint 743 Negative character constant Message-ID: <20180816085235.A411E98B83@lists.varnish-cache.org> commit ca9fda6420d6e67c3a88ea7e6902e6a6ef34e1b2 Author: Nils Goroll Date: Thu Apr 5 11:40:33 2018 +0200 flexelint 743 Negative character constant diff --git a/bin/varnishd/cache/cache_esi_parse.c b/bin/varnishd/cache/cache_esi_parse.c index ef72eebc8..1c1f13a04 100644 --- a/bin/varnishd/cache/cache_esi_parse.c +++ b/bin/varnishd/cache/cache_esi_parse.c @@ -616,7 +616,8 @@ VEP_Parse(struct vep_state *vep, const char *p, size_t l) */ if (vep->state == VEP_START) { - if (FEATURE(FEATURE_ESI_REMOVE_BOM) && *p == '\xeb') { + if (FEATURE(FEATURE_ESI_REMOVE_BOM) && + *p == (char)0xeb) { vep->match = vep_match_bom; vep->state = VEP_MATCH; } else @@ -638,7 +639,7 @@ VEP_Parse(struct vep_state *vep, const char *p, size_t l) if (p < e && *p == '<') { p++; vep->state = VEP_STARTTAG; - } else if (p < e && *p == '\xeb') { + } else if (p < e && *p == (char)0xeb) { VSLb(vep->vc->wrk->vsl, SLT_ESI_xmlerror, "No ESI processing, " "first char not '<' but BOM." From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:35 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:35 +0000 (UTC) Subject: [6.0] e4a727803 flexelint 534: Ignoring return value of function Message-ID: <20180816085235.D052898BA1@lists.varnish-cache.org> commit e4a727803c67849c3f2a6a4debd9353baad505f1 Author: Nils Goroll Date: Thu Apr 5 11:43:39 2018 +0200 flexelint 534: Ignoring return value of function diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index e2381a475..ad7e31249 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -102,14 +102,14 @@ THR_SetName(const char *name) AZ(pthread_setspecific(name_key, name)); #if defined(HAVE_PTHREAD_SET_NAME_NP) - pthread_set_name_np(pthread_self(), name); + (void)pthread_set_name_np(pthread_self(), name); #elif defined(HAVE_PTHREAD_SETNAME_NP) #if defined(__APPLE__) - pthread_setname_np(name); + (void)pthread_setname_np(name); #elif defined(__NetBSD__) - pthread_setname_np(pthread_self(), "%s", (char *)(uintptr_t)name); + (void)pthread_setname_np(pthread_self(), "%s", (char *)(uintptr_t)name); #else - pthread_setname_np(pthread_self(), name); + (void)pthread_setname_np(pthread_self(), name); #endif #endif } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:35 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:35 +0000 (UTC) Subject: [6.0] 1f8718b75 gc unused includes Message-ID: <20180816085236.18D6198BC2@lists.varnish-cache.org> commit 1f8718b75a5ab204cba6954ad35d41880ff29bf6 Author: Nils Goroll Date: Thu Apr 5 11:45:13 2018 +0200 gc unused includes diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c index 04e425ce7..9ae48331b 100644 --- a/bin/varnishd/cache/cache_shmlog.c +++ b/bin/varnishd/cache/cache_shmlog.c @@ -35,7 +35,6 @@ #include #include -#include "vend.h" #include "vgz.h" #include "vsl_priv.h" #include "vmb.h" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:36 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:36 +0000 (UTC) Subject: [6.0] e8949a68e flexelint 838: Previously assigned value ... has not been used Message-ID: <20180816085236.42DDE98BD8@lists.varnish-cache.org> commit e8949a68e45849498c3ac157542021467deb29f2 Author: Nils Goroll Date: Thu Apr 5 11:50:34 2018 +0200 flexelint 838: Previously assigned value ... has not been used diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c index 5f821ac77..022224dbf 100644 --- a/bin/varnishd/proxy/cache_proxy_proto.c +++ b/bin/varnishd/proxy/cache_proxy_proto.c @@ -311,7 +311,7 @@ vpx_proto2(const struct worker *wrk, struct req *req) int l, hdr_len; uintptr_t *up; uint16_t *tlv_len_p; - uint16_t tlv_len = 0; + uint16_t tlv_len; const uint8_t *p; char *d, *tlv_start; sa_family_t pfam = 0xff; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:36 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:36 +0000 (UTC) Subject: [6.0] 63c6ba304 the use case referenced here never made it upstream Message-ID: <20180816085236.6F27398BF3@lists.varnish-cache.org> commit 63c6ba3041670f39601dda6f703227604cb6d7a2 Author: Nils Goroll Date: Thu Apr 5 12:44:37 2018 +0200 the use case referenced here never made it upstream diff --git a/bin/varnishd/mgt/mgt_jail_solaris.c b/bin/varnishd/mgt/mgt_jail_solaris.c index 8925d92df..3b8de0861 100644 --- a/bin/varnishd/mgt/mgt_jail_solaris.c +++ b/bin/varnishd/mgt/mgt_jail_solaris.c @@ -355,8 +355,6 @@ vjs_add_permitted(priv_set_t *pset, enum jail_gen_e jge) case JAILG_SUBPROC_VCLLOAD: break; case JAILG_SUBPROC_WORKER: - /* for raising limits in cache_waiter_ports.c */ - AZ(priv_addset(pset, PRIV_SYS_RESOURCE)); break; default: INCOMPL(); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:36 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:36 +0000 (UTC) Subject: [6.0] 089ec522a oops Message-ID: <20180816085236.A6EE798C0A@lists.varnish-cache.org> commit 089ec522a6a970b1c68ad9058b3102a06bff367c Author: Nils Goroll Date: Thu Apr 5 14:16:31 2018 +0200 oops diff --git a/bin/varnishd/mgt/mgt_jail_solaris.c b/bin/varnishd/mgt/mgt_jail_solaris.c index 3b8de0861..ef80c909b 100644 --- a/bin/varnishd/mgt/mgt_jail_solaris.c +++ b/bin/varnishd/mgt/mgt_jail_solaris.c @@ -349,6 +349,7 @@ vjs_add_effective(priv_set_t *pset, enum jail_gen_e jge) static void vjs_add_permitted(priv_set_t *pset, enum jail_gen_e jge) { + (void) pset; switch (jge) { case JAILG_SUBPROC_VCC: case JAILG_SUBPROC_CC: From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:36 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:36 +0000 (UTC) Subject: [6.0] 4d2c0c543 support for vmod_unix on solar-ish OSes Message-ID: <20180816085236.CEC1B98C22@lists.varnish-cache.org> commit 4d2c0c543a0ffc24f810111cd42dd8e435815466 Author: Nils Goroll Date: Thu Apr 5 13:58:19 2018 +0200 support for vmod_unix on solar-ish OSes note on jail_solaris: ideally, vmods could tell the jails about privileges they require, but for now (and because vmod_unix lives in varnish-cache), just add the required privilege to the permitted set. I have also considered the option to add additional privileges via the -j argument (and actually would still want to add that somewhen), but for this purpose, varnish should really DTRT by default. note on priv_allocset: Most of the sun folk had proven to be good interface designers, but an API which requires dynamic allocation/deallocation really does not play well with my efficiency fetish. So good we got library constructors/destructors. note on getpeerucred: basically the same thing, but this time they at least added ucred_size(). Not intended for use like this, but anyway.... diff --git a/bin/varnishd/mgt/mgt_jail_solaris.c b/bin/varnishd/mgt/mgt_jail_solaris.c index ef80c909b..dc1921297 100644 --- a/bin/varnishd/mgt/mgt_jail_solaris.c +++ b/bin/varnishd/mgt/mgt_jail_solaris.c @@ -356,6 +356,8 @@ vjs_add_permitted(priv_set_t *pset, enum jail_gen_e jge) case JAILG_SUBPROC_VCLLOAD: break; case JAILG_SUBPROC_WORKER: + /* vmod_unix getpeerucred() */ + AZ(priv_addset(pset, PRIV_PROC_INFO)); break; default: INCOMPL(); diff --git a/configure.ac b/configure.ac index ad2850737..2e25adf05 100644 --- a/configure.ac +++ b/configure.ac @@ -217,6 +217,7 @@ AC_CHECK_FUNCS([fallocate]) AC_CHECK_FUNCS([closefrom]) AC_CHECK_FUNCS([sigaltstack]) AC_CHECK_FUNCS([getpeereid]) +AC_CHECK_FUNCS([getpeerucred]) save_LIBS="${LIBS}" LIBS="${PTHREAD_LIBS}" diff --git a/lib/libvmod_unix/cred_compat.h b/lib/libvmod_unix/cred_compat.h index 6a79636f5..3c5ff080e 100644 --- a/lib/libvmod_unix/cred_compat.h +++ b/lib/libvmod_unix/cred_compat.h @@ -25,8 +25,6 @@ * */ -#include "config.h" - #include #include #include @@ -37,11 +35,35 @@ #if defined(HAVE_GETPEERUCRED) #include +# if defined(HAVE_SETPPRIV) +# include +static priv_set_t *priv_proc_info = NULL; +# endif #endif #define CREDS_FAIL -1 #define NOT_SUPPORTED -2 +#if defined(HAVE_GETPEERUCRED) && defined(HAVE_SETPPRIV) +static void __attribute__((constructor)) +cred_compat_init(void) +{ + AZ(priv_proc_info); + priv_proc_info = priv_allocset(); + AN(priv_proc_info); + AZ(priv_addset(priv_proc_info, PRIV_PROC_INFO)); +} + +static void __attribute__((destructor)) +cred_compat_fini(void) +{ + if (priv_proc_info == NULL) + return; + priv_freeset(priv_proc_info); + priv_proc_info = NULL; +} +#endif + static int get_ids(int fd, uid_t *uid, gid_t *gid) { @@ -65,6 +87,33 @@ get_ids(int fd, uid_t *uid, gid_t *gid) return (CREDS_FAIL); return (0); +#elif defined(HAVE_GETPEERUCRED) + char buf[ucred_size()]; + ucred_t *ucredp = (ucred_t *)buf; + +# if defined(HAVE_SETPPRIV) + priv_set_t *priv = NULL; + + errno = 0; + if (! priv_ineffect(PRIV_PROC_INFO)) { + priv = priv_proc_info; + if (setppriv(PRIV_ON, PRIV_EFFECTIVE, priv)) + return (CREDS_FAIL); + } +# endif + + errno = 0; + if (getpeerucred(fd, &ucredp)) + return (CREDS_FAIL); + *uid = ucred_getruid(ucredp); + *gid = ucred_getrgid(ucredp); + +# if defined(HAVE_SETPPRIV) + if (priv != NULL) + AZ(setppriv(PRIV_OFF, PRIV_EFFECTIVE, priv)); // waive +# endif + + return (0); #else (void) fd; (void) uid; diff --git a/lib/libvmod_unix/vmod_unix.c b/lib/libvmod_unix/vmod_unix.c index ee1f3e002..f51c10883 100644 --- a/lib/libvmod_unix/vmod_unix.c +++ b/lib/libvmod_unix/vmod_unix.c @@ -25,7 +25,7 @@ * */ -#include "cred_compat.h" +#include "config.h" #include #include @@ -35,6 +35,7 @@ #include "vcl.h" #include "common/heritage.h" +#include "cred_compat.h" #include "vcc_if.h" #define FAIL(ctx, msg) \ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:37 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:37 +0000 (UTC) Subject: [6.0] 35f79a696 More code coverage of Teken Message-ID: <20180816085237.108C198C3C@lists.varnish-cache.org> commit 35f79a69668b56c112b297501b815316ec1cb58d Author: Poul-Henning Kamp Date: Fri Apr 6 10:52:53 2018 +0000 More code coverage of Teken diff --git a/bin/varnishtest/tests/a00001.vtc b/bin/varnishtest/tests/a00001.vtc index 1dd3f3634..16f0437fc 100644 --- a/bin/varnishtest/tests/a00001.vtc +++ b/bin/varnishtest/tests/a00001.vtc @@ -2,7 +2,7 @@ varnishtest "Test Teken terminal emulator" feature cmd "vttest --version 2>&1 | grep -q Usage" -process p4 -dump {vttest} -start +process p4 {vttest} -start process p4 -expect-text 21 11 "Enter choice number (0 - 12):" process p4 -screen_dump @@ -37,6 +37,73 @@ process p4 -writehex 0d process p4 -expect-text 21 11 "Enter choice number (0 - 12):" process p4 -screen_dump +process p4 -writehex "32 0d" +process p4 -expect-text 8 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 5 1 "should look the same. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 0 0 "This is 132 column mode, light background.Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 0 0 "This is 80 column mode, light background.Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 0 0 "This is 132 column mode, dark background.Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 0 0 "This is 80 column mode, dark background.Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 0 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 3 1 "Soft scroll down region [1..24] size 24 Line 28" +process p4 -expect-text 1 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 0 1 "Jump scroll down region [12..13] size 2 Line 29" +process p4 -expect-text 0 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 3 1 "Jump scroll down region [1..24] size 24 Line 28" +process p4 -expect-text 1 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 23 0 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 1 0 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 23 1 "Dark background. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 23 1 "Light background. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 24 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 21 11 "Enter choice number (0 - 12):" +process p4 -screen_dump + process p4 -writehex "30 0d" process p4 -expect-text 12 30 "That's all, folks!" process p4 -screen_dump From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:37 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:37 +0000 (UTC) Subject: [6.0] 559f75fdc VMOD unix obtains effective uid/gid on solarishy platforms. Message-ID: <20180816085237.3775B98C59@lists.varnish-cache.org> commit 559f75fdcfb52b0b371ea4c5b420c8f0f9bf221f Author: Geoff Simmons Date: Fri Apr 6 14:51:45 2018 +0200 VMOD unix obtains effective uid/gid on solarishy platforms. Not real ids; for consistency with the other platforms. diff --git a/lib/libvmod_unix/cred_compat.h b/lib/libvmod_unix/cred_compat.h index 3c5ff080e..843793a75 100644 --- a/lib/libvmod_unix/cred_compat.h +++ b/lib/libvmod_unix/cred_compat.h @@ -105,8 +105,8 @@ get_ids(int fd, uid_t *uid, gid_t *gid) errno = 0; if (getpeerucred(fd, &ucredp)) return (CREDS_FAIL); - *uid = ucred_getruid(ucredp); - *gid = ucred_getrgid(ucredp); + *uid = ucred_geteuid(ucredp); + *gid = ucred_getegid(ucredp); # if defined(HAVE_SETPPRIV) if (priv != NULL) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:37 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:37 +0000 (UTC) Subject: [6.0] 422a90c4a Document support of SunOS and friends in VMOD unix. Message-ID: <20180816085237.5D81A98C65@lists.varnish-cache.org> commit 422a90c4affb95bf7b8c2663a39fd54ce43475db Author: Geoff Simmons Date: Fri Apr 6 15:37:22 2018 +0200 Document support of SunOS and friends in VMOD unix. diff --git a/lib/libvmod_unix/vmod.vcc b/lib/libvmod_unix/vmod.vcc index d698a918c..e70a092d3 100644 --- a/lib/libvmod_unix/vmod.vcc +++ b/lib/libvmod_unix/vmod.vcc @@ -53,6 +53,12 @@ one of the following: * the socket option ``SO_PEERCRED`` for ``getsockopt(2)`` (Linux) +* ``getpeerucred(3C)`` (SunOS and descendants) + +On SunOS and friends, the ``PRIV_PROC_INFO`` privilege set is added to +the Varnish child process while the VMOD is loaded, see +``setppriv(2)``. + On most platforms, the value returned is the effective user or group that was valid when the peer process initiated the connection. @@ -104,3 +110,5 @@ SEE ALSO * :ref:`vcl(7)` * ``getpeereid(3)`` * ``getsockopt(2)`` +* ``getpeerucred(3C)`` +* ``setppriv(2)`` From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:37 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:37 +0000 (UTC) Subject: [6.0] 29aa1a394 Document VMOD unix getpeerucred(3) support in changes.rst. Message-ID: <20180816085237.9BF1698C86@lists.varnish-cache.org> commit 29aa1a39452c51290aca9dd45fbb29309aabe7c4 Author: Geoff Simmons Date: Fri Apr 6 15:57:44 2018 +0200 Document VMOD unix getpeerucred(3) support in changes.rst. Tweaked: doc/changes.rst diff --git a/doc/changes.rst b/doc/changes.rst index bb85dc2a4..9591ce872 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,6 +1,11 @@ -==================== -Varnish Cache master -==================== +================================ +Varnish Cache 6.0.1 (ongoing) +================================ + +VCL and bundled VMODs +--------------------- + +* VMOD unix now supports the ``getpeerucred(3)`` case. bundled tools ------------- From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:37 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:37 +0000 (UTC) Subject: [6.0] 861f8f490 varnishstat: get uptime for averages even if not in filter Message-ID: <20180816085237.C7C0498CA2@lists.varnish-cache.org> commit 861f8f4904ee238dc4c1a4b7b3793f7182c8c506 Author: Nils Goroll Date: Fri Apr 6 17:18:19 2018 +0200 varnishstat: get uptime for averages even if not in filter fixes #2639 diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c index 6b33e007b..0a78a4513 100644 --- a/bin/varnishstat/varnishstat.c +++ b/bin/varnishstat/varnishstat.c @@ -199,12 +199,17 @@ do_once_cb(void *priv, const struct VSC_point * const pt) static void do_once(struct vsm *vsm, struct vsc *vsc) { + struct vsc *vsconce = VSC_New(); struct once_priv op; + AN(vsconce); + AN(VSC_Arg(vsconce, 'f', "MAIN.uptime")); + memset(&op, 0, sizeof op); op.pad = 18; - (void)VSC_Iter(vsc, vsm, do_once_cb_first, &op); + (void)VSC_Iter(vsconce, vsm, do_once_cb_first, &op); + VSC_Destroy(&vsconce, vsm); (void)VSC_Iter(vsc, vsm, do_once_cb, &op); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:37 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:37 +0000 (UTC) Subject: [6.0] f3c8cd4d6 fix proxy backend in pipe mode Message-ID: <20180816085238.0372798CB6@lists.varnish-cache.org> commit f3c8cd4d64820b5824905a2464a09541cbd30074 Author: Nils Goroll Date: Thu Mar 15 16:58:42 2018 +0100 fix proxy backend in pipe mode Fixes #2613 diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 4c8fad090..e327c0d53 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -693,6 +693,8 @@ cnt_pipe(struct worker *wrk, struct req *req) VSLb(bo->vsl, SLT_Begin, "bereq %u pipe", VXID(req->vsl->wid)); VSLb(req->vsl, SLT_Link, "bereq %u pipe", VXID(bo->vsl->wid)); THR_SetBusyobj(bo); + bo->sp = req->sp; + SES_Ref(bo->sp); HTTP_Setup(bo->bereq, bo->ws, bo->vsl, SLT_BereqMethod); http_FilterReq(bo->bereq, req->http, 0); // XXX: 0 ? @@ -726,6 +728,7 @@ cnt_pipe(struct worker *wrk, struct req *req) WRONG("Illegal return from vcl_pipe{}"); } http_Teardown(bo->bereq); + SES_Rel(bo->sp); VBO_ReleaseBusyObj(wrk, &bo); THR_SetBusyobj(NULL); return (nxt); diff --git a/bin/varnishtest/tests/o00002.vtc b/bin/varnishtest/tests/o00002.vtc index 13fba7dfc..9217afac7 100644 --- a/bin/varnishtest/tests/o00002.vtc +++ b/bin/varnishtest/tests/o00002.vtc @@ -34,6 +34,13 @@ server s1 { expect req.http.xyzzy1 == 4444 expect req.http.x-forwarded-for == "1:f::2, 1:f::2" txresp -body "proxy4" + + rxreq + expect req.url == "/pipe" + expect req.http.xyzzy1 == req.http.xyzzy2 + expect req.http.xyzzy1 == 5555 + expect req.http.x-forwarded-for == "1:f::2, 1:f::2" + txresp -hdr "Connection: close" -body "pipe" } -start varnish v1 -proto PROXY -vcl+backend { @@ -64,6 +71,9 @@ varnish v2 -proto PROXY -vcl { } else { set req.backend_hint = bp2; } + if (req.url ~ "^/pipe") { + return (pipe); + } } sub vcl_deliver { set resp.http.connection = "close"; @@ -97,3 +107,11 @@ client c1 -connect ${v2_sock} -proxy1 "[1:f::2]:4444 [5:a::8]:5678" { expect resp.body == "proxy4" } -run delay .2 + +client c1 -connect ${v2_sock} -proxy1 "[1:f::2]:5555 [5:a::8]:5678" { + txreq -url /pipe + rxresp + expect resp.body == "pipe" + expect resp.http.Connection == "close" + expect_close +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:38 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:38 +0000 (UTC) Subject: [6.0] 43f1ca560 Specifying the process->spec twice in one line is almost certainly an error, so make it one. Message-ID: <20180816085238.3F42198CCB@lists.varnish-cache.org> commit 43f1ca560f12ed49d126c85d58574d765f21d007 Author: Poul-Henning Kamp Date: Fri Apr 6 19:38:22 2018 +0000 Specifying the process->spec twice in one line is almost certainly an error, so make it one. diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 0dbe46fc0..1bbf13732 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -859,6 +859,7 @@ cmd_process(CMD_ARGS) struct process *p, *p2; uintmax_t u, v; unsigned lin,col; + int spec_set = 0; (void)priv; (void)cmd; @@ -1009,9 +1010,10 @@ cmd_process(CMD_ARGS) av++; continue; } - if (**av == '-') + if (**av == '-' || spec_set) vtc_fatal(p->vl, "Unknown process argument: %s", *av); REPLACE(p->spec, *av); + spec_set = 1; } } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:38 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:38 +0000 (UTC) Subject: [6.0] c4e07ea1a Report if killing haproxy fails Message-ID: <20180816085238.6372798CDE@lists.varnish-cache.org> commit c4e07ea1a7211b36ed7a265d2f4af8702c883f2f Author: Poul-Henning Kamp Date: Fri Apr 6 21:41:46 2018 +0000 Report if killing haproxy fails diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index f8eec1215..21a6cb34d 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -324,6 +324,9 @@ haproxy_wait(struct haproxy *h) vtc_log(h->vl, 2, "Stop HAproxy pid=%ld", (long)h->pid); h->kill_status = kill(h->pid, HAPROXY_SIGNAL); h->kill_errno = errno; + if (h->kill_status) + vtc_log(h->vl, 4, "Kill=%d: %s", + h->kill_status, strerror(h->kill_errno)); h->expect_signal = -HAPROXY_SIGNAL; // XXX: loop over kills to ESRCH ? } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:38 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:38 +0000 (UTC) Subject: [6.0] 743c06155 Try even harder to kill haproxy during cleanup Message-ID: <20180816085238.8C37398CEE@lists.varnish-cache.org> commit 743c0615512141677a37e9d9d59c359e53dca45f Author: Poul-Henning Kamp Date: Sat Apr 7 05:53:05 2018 +0000 Try even harder to kill haproxy during cleanup diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 21a6cb34d..ea66f81e7 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -70,8 +70,7 @@ struct haproxy { pthread_t tp; int expect_exit; int expect_signal; - int kill_status; - int kill_errno; + int its_dead_jim; const char *cli_fn; @@ -213,7 +212,9 @@ haproxy_thread(void *priv) struct haproxy *h; CAST_OBJ_NOTNULL(h, priv, HAPROXY_MAGIC); - return (vtc_record(h->vl, h->fds[0], h->msgs)); + (void)vtc_record(h->vl, h->fds[0], h->msgs); + h->its_dead_jim = 1; + return (NULL); } /********************************************************************** @@ -311,6 +312,7 @@ static void haproxy_wait(struct haproxy *h) { void *p; + int i; vtc_log(h->vl, 2, "Wait"); @@ -319,16 +321,16 @@ haproxy_wait(struct haproxy *h) closefd(&h->fds[1]); - if (!h->opt_check_mode) { + while (!h->opt_check_mode && !h->its_dead_jim) { assert(h->pid > 0); vtc_log(h->vl, 2, "Stop HAproxy pid=%ld", (long)h->pid); - h->kill_status = kill(h->pid, HAPROXY_SIGNAL); - h->kill_errno = errno; - if (h->kill_status) - vtc_log(h->vl, 4, "Kill=%d: %s", - h->kill_status, strerror(h->kill_errno)); + i= kill(h->pid, HAPROXY_SIGNAL); h->expect_signal = -HAPROXY_SIGNAL; - // XXX: loop over kills to ESRCH ? + if (i && errno == ESRCH) + break; + if (i) + vtc_log(h->vl, 4, "Kill=%d: %s", i, strerror(errno)); + usleep(100000); } AZ(pthread_join(h->tp, &p)); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:38 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:38 +0000 (UTC) Subject: [6.0] 42e15a10f Escalate the signals if HAproxy refuses to die Message-ID: <20180816085238.BD72798D05@lists.varnish-cache.org> commit 42e15a10f13c25e7c96e25d6d0f3cb6a1a165ac8 Author: Poul-Henning Kamp Date: Sat Apr 7 10:27:04 2018 +0000 Escalate the signals if HAproxy refuses to die diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index ea66f81e7..73f42b879 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -312,7 +312,7 @@ static void haproxy_wait(struct haproxy *h) { void *p; - int i; + int i, n, sig; vtc_log(h->vl, 2, "Wait"); @@ -321,16 +321,28 @@ haproxy_wait(struct haproxy *h) closefd(&h->fds[1]); + sig = SIGINT; + n = 0; + vtc_log(h->vl, 2, "Stop HAproxy pid=%ld", (long)h->pid); while (!h->opt_check_mode && !h->its_dead_jim) { assert(h->pid > 0); - vtc_log(h->vl, 2, "Stop HAproxy pid=%ld", (long)h->pid); - i= kill(h->pid, HAPROXY_SIGNAL); - h->expect_signal = -HAPROXY_SIGNAL; - if (i && errno == ESRCH) - break; - if (i) - vtc_log(h->vl, 4, "Kill=%d: %s", i, strerror(errno)); + if (n == 0) { + i= kill(h->pid, sig); + vtc_log(h->vl, 4, + "Kill(%d)=%d: %s", sig, i, strerror(errno)); + h->expect_signal = -sig; + if (i && errno == ESRCH) + break; + } usleep(100000); + if (++n == 20) { + switch (sig) { + case SIGINT: sig = SIGTERM ; break; + case SIGTERM: sig = SIGKILL ; break; + default: break; + } + n = 0; + } } AZ(pthread_join(h->tp, &p)); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:38 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:38 +0000 (UTC) Subject: [6.0] 4bc283830 Even more Teken coverage Message-ID: <20180816085238.E324498D32@lists.varnish-cache.org> commit 4bc28383037a04398f14bb261d90c2de1d33ec73 Author: Poul-Henning Kamp Date: Sat Apr 7 12:59:33 2018 +0000 Even more Teken coverage diff --git a/bin/varnishtest/tests/a00001.vtc b/bin/varnishtest/tests/a00001.vtc index 16f0437fc..dfca677e0 100644 --- a/bin/varnishtest/tests/a00001.vtc +++ b/bin/varnishtest/tests/a00001.vtc @@ -7,6 +7,7 @@ process p4 {vttest} -start process p4 -expect-text 21 11 "Enter choice number (0 - 12):" process p4 -screen_dump +# 1. Test of cursor movements process p4 -writehex "31 0d" process p4 -expect-text 14 61 "RETURN" process p4 -screen_dump @@ -37,6 +38,7 @@ process p4 -writehex 0d process p4 -expect-text 21 11 "Enter choice number (0 - 12):" process p4 -screen_dump +# 2. Test of screen features process p4 -writehex "32 0d" process p4 -expect-text 8 1 "Push " process p4 -screen_dump @@ -104,6 +106,105 @@ process p4 -writehex 0d process p4 -expect-text 21 11 "Enter choice number (0 - 12):" process p4 -screen_dump +# 4. Test of double-sized characters +process p4 -writehex "34 0d" +process p4 -expect-text 21 1 "This is not a double-width line" +process p4 -expect-text 23 1 "Push " +process p4 -screen_dump + +process p4 -writehex "0d" +process p4 -expect-text 21 1 "This **is** a double-width line" +process p4 -expect-text 23 1 "Push " +process p4 -screen_dump + +process p4 -writehex "0d" +process p4 -expect-text 21 1 "This is not a double-width line" +process p4 -expect-text 23 1 "Push " +process p4 -screen_dump + +process p4 -writehex "0d" +process p4 -expect-text 21 1 "This **is** a double-width line" +process p4 -expect-text 23 1 "Push " +process p4 -screen_dump + +process p4 -writehex "0d" +delay 2 +process p4 -expect-text 23 41 "Push " +process p4 -screen_dump + +process p4 -writehex "0d" +delay 2 +process p4 -expect-text 1 1 "Exactly half of the box should remain. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 21 11 "Enter choice number (0 - 12):" +process p4 -screen_dump + +# 8. Test of VT102 features (Insert/Delete Char/Line) +process p4 -writehex "38 0d" +process p4 -expect-text 4 1 "Screen accordion test (Insert & Delete Line). Push D" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 2 45 "nothing more. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 4 59 "*B'. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 4 52 "'AB'. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 5 1 "by one. Push E" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 5 1 "by one. Push EEEEEEEEEEEEE " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 10 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 4 1 "Screen accordion test (Insert & Delete Line). Push D" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 2 45 "nothing more. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 4 59 "*B'. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 4 52 "'AB'. Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 5 1 "by one. Push E" +process p4 -screen_dump + + +process p4 -writehex 0d +process p4 -expect-text 5 59 "EEE " +process p4 -expect-text 5 1 "by one. Push E" +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 10 1 "Push " +process p4 -screen_dump + +process p4 -writehex 0d +process p4 -expect-text 21 11 "Enter choice number (0 - 12):" +process p4 -screen_dump + +# 0. Exit process p4 -writehex "30 0d" process p4 -expect-text 12 30 "That's all, folks!" process p4 -screen_dump diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 1bbf13732..be763239a 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -289,7 +289,7 @@ static void term_expect_text(struct process *pp, const char *lin, const char *col, const char *pat) { - int x, y, l; + int x, y, l, d = 10000; char *t; y = strtoul(lin, NULL, 0); @@ -303,8 +303,10 @@ term_expect_text(struct process *pp, "text at %d,%d: '%.*s'", y, x, l, t); } AZ(pthread_mutex_unlock(&pp->mtx)); - usleep(1000000); + usleep(d); AZ(pthread_mutex_lock(&pp->mtx)); + if (d < 300000) + d += d; } AZ(pthread_mutex_unlock(&pp->mtx)); vtc_log(pp->vl, 4, "found expected text at %d,%d: '%s'", y, x, pat); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:39 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:39 +0000 (UTC) Subject: [6.0] 9bcae3ecc Add a delay to allow the utils to attach the shmem before running the transaction. Message-ID: <20180816085239.19FAA98D5A@lists.varnish-cache.org> commit 9bcae3ecc0a10abebff689520eabff51cdfd3ea7 Author: Poul-Henning Kamp Date: Sat Apr 7 14:41:07 2018 +0000 Add a delay to allow the utils to attach the shmem before running the transaction. diff --git a/bin/varnishtest/tests/u00009.vtc b/bin/varnishtest/tests/u00009.vtc index eb587bcbe..90b7a3dd6 100644 --- a/bin/varnishtest/tests/u00009.vtc +++ b/bin/varnishtest/tests/u00009.vtc @@ -9,13 +9,15 @@ varnish v1 -vcl+backend {} -start process p1 -dump {varnishhist -n ${v1_name}} -start -process p1 -expect-text 0 0 {1e2} +process p1 -expect-text 24 0 {1e2} + +delay 1 client c1 { txreq rxresp } -run -process p1 -expect-text 0 0 {#} +process p1 -expect-text 22 0 {#} process p1 -screen_dump -write {q} -wait diff --git a/bin/varnishtest/tests/u00010.vtc b/bin/varnishtest/tests/u00010.vtc index 9104c489b..fc555ff8a 100644 --- a/bin/varnishtest/tests/u00010.vtc +++ b/bin/varnishtest/tests/u00010.vtc @@ -11,6 +11,8 @@ process p1 -dump {varnishtop -n ${v1_name}} -start process p1 -expect-text 1 1 {list length} +delay 1 + client c1 { txreq rxresp From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:39 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:39 +0000 (UTC) Subject: [6.0] 4a4dd0510 Remove parts of the libvgz API which we dont use. Message-ID: <20180816085239.64F5D98D7A@lists.varnish-cache.org> commit 4a4dd05105e8e4521a274814b637c8550e60c3d6 Author: Poul-Henning Kamp Date: Sun Apr 8 08:02:23 2018 +0000 Remove parts of the libvgz API which we dont use. diff --git a/lib/libvgz/Makefile.am b/lib/libvgz/Makefile.am index 74afccf9e..db9a48bdc 100644 --- a/lib/libvgz/Makefile.am +++ b/lib/libvgz/Makefile.am @@ -9,13 +9,11 @@ libvgz_a_CFLAGS = -D_LARGEFILE64_SOURCE=1 -DZLIB_CONST \ libvgz_a_SOURCES = \ adler32.c \ - compress.c \ crc32.c \ crc32.h \ deflate.c \ deflate.h \ gzguts.h \ - infback.c \ inffast.c \ inffast.h \ inffixed.h \ @@ -25,7 +23,6 @@ libvgz_a_SOURCES = \ inftrees.h \ trees.c \ trees.h \ - uncompr.c \ zconf.h \ vgz.h \ zutil.c \ diff --git a/lib/libvgz/compress.c b/lib/libvgz/compress.c deleted file mode 100644 index 6134fad12..000000000 --- a/lib/libvgz/compress.c +++ /dev/null @@ -1,86 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "vgz.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong left; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/lib/libvgz/infback.c b/lib/libvgz/infback.c deleted file mode 100644 index d632415f1..000000000 --- a/lib/libvgz/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = "invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = "invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = "too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = "invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = "invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = "invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = "invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = "invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = "invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = "invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = "invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = "invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/lib/libvgz/uncompr.c b/lib/libvgz/uncompr.c deleted file mode 100644 index a1212de9a..000000000 --- a/lib/libvgz/uncompr.c +++ /dev/null @@ -1,93 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "vgz.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} - -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return uncompress2(dest, destLen, source, &sourceLen); -} From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:39 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:39 +0000 (UTC) Subject: [6.0] 981f9ad76 Include headers to compile on musl Message-ID: <20180816085239.8FA1098D92@lists.varnish-cache.org> commit 981f9ad76cb8ca9b202b4434f2634b9f24a0cc0b Author: Guillaume Quintard Date: Sat Apr 7 14:36:29 2018 +0200 Include headers to compile on musl diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c index 035e6b20a..25bdfda24 100644 --- a/bin/varnishtest/vtc_barrier.c +++ b/bin/varnishtest/vtc_barrier.c @@ -35,6 +35,7 @@ #include #include +#include /* for MUSL */ #include "vtc.h" #include "vtcp.h" diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index e852a0d63..e268326c1 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -40,6 +40,7 @@ #include #include #include +#include /* for MUSL */ #include "compat/daemon.h" #include "vdef.h" diff --git a/lib/libvarnishapi/vxp.c b/lib/libvarnishapi/vxp.c index 039fafe04..5c5049827 100644 --- a/lib/libvarnishapi/vxp.c +++ b/lib/libvarnishapi/vxp.c @@ -33,6 +33,7 @@ #include #include #include +#include /* for MUSL */ #include "vdef.h" #include "vas.h" diff --git a/lib/libvarnishapi/vxp_lexer.c b/lib/libvarnishapi/vxp_lexer.c index 527bbb736..584cf4f97 100644 --- a/lib/libvarnishapi/vxp_lexer.c +++ b/lib/libvarnishapi/vxp_lexer.c @@ -33,6 +33,7 @@ #include #include #include +#include /* for MUSL */ #include "vdef.h" #include "vas.h" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:39 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:39 +0000 (UTC) Subject: [6.0] 18c9e0c24 warning and advise about backend proxy connections Message-ID: <20180816085239.B27C698DB2@lists.varnish-cache.org> commit 18c9e0c247a1b3f6c0921e66e4459353a7f8bce6 Author: Nils Goroll Date: Mon Apr 9 14:23:06 2018 +0200 warning and advise about backend proxy connections Ref #2622 diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index d2eec3d13..d2263dc37 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -252,6 +252,21 @@ parameters. The following attributes are available: The PROXY protocol version Varnish should use when connecting to this backend. Allowed values are ``1`` and ``2``. + *Notice* this setting will lead to backend connections being used + for a single request only (subject to future improvements). Thus, + extra care should be taken to avoid running into failing backend + connections with EADDRNOTAVAIL due to no local ports being + available. Possible options are: + + * Use additional backend connections to extra IP addresses or TCP + ports + + * Increase the number of available ports (Linux sysctl + ``net.ipv4.ip_local_port_range``) + + * Reuse backend connection ports early (Linux sysctl + ``net.ipv4.tcp_tw_reuse``) + ``.max_connections`` Maximum number of open connections towards this backend. If Varnish reaches the maximum Varnish it will start failing From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:39 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:39 +0000 (UTC) Subject: [6.0] d03fe3361 Rewrite the proxy TLV wandering code, hoping coverity can make better sense of it now. Message-ID: <20180816085239.D7C0598DD6@lists.varnish-cache.org> commit d03fe33614cd1b78e1e853244a5937d638f19e16 Author: Poul-Henning Kamp Date: Tue Apr 10 08:55:46 2018 +0000 Rewrite the proxy TLV wandering code, hoping coverity can make better sense of it now. diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c index 022224dbf..32ddd6f61 100644 --- a/bin/varnishd/proxy/cache_proxy_proto.c +++ b/bin/varnishd/proxy/cache_proxy_proto.c @@ -42,6 +42,13 @@ #include "vsa.h" #include "vtcp.h" +struct vpx_tlv { + unsigned magic; +#define VPX_TLV_MAGIC 0xdeb9a4a5 + unsigned len; + char tlv[1]; +}; + /********************************************************************** * PROXY 1 protocol */ @@ -156,17 +163,6 @@ vpx_proto1(const struct worker *wrk, const struct req *req) * PROXY 2 protocol */ -struct pp2_tlv { - uint8_t type; - uint8_t length_hi; - uint8_t length_lo; -}__attribute__((packed)); - -struct pp2_tlv_ssl { - uint8_t client; - uint32_t verify; -}__attribute__((packed)); - static const char vpx2_sig[] = { '\r', '\n', '\r', '\n', '\0', '\r', '\n', 'Q', 'U', 'I', 'T', '\n', @@ -248,60 +244,85 @@ static uint32_t crc32c(const uint8_t *buf, int len) return (crc ^ 0xffffffff); } +struct vpx_tlv_iter { + uint8_t t; + void *p; + uint16_t l; + const char *e; + + unsigned char *_p; + uint16_t _l; +}; + +static void +vpx_tlv_iter0(struct vpx_tlv_iter *vpi, void *p, unsigned l) +{ + + AN(p); + assert(l < 65536); + memset(vpi, 0, sizeof *vpi); + vpi->_p = p; + vpi->_l = l; +} + +static int +vpx_tlv_itern(struct vpx_tlv_iter *vpi) +{ + if (vpi->_l == 0 || vpi->e != NULL) + return (0); + if (vpi->_l < 3) { + vpi->e = "Dribble bytes"; + return (0); + } + vpi->t = *vpi->_p; + vpi->l = vbe16dec(vpi->_p + 1); + if (vpi->l + 3 > vpi->_l) { + vpi->e = "Length Error"; + return (0); + } + vpi->p = vpi->_p + 3; + vpi->_p += 3 + vpi->l; + vpi->_l -= 3 + vpi->l; + return (1); +} + +#define VPX_TLV_FOREACH(ptr, len, itv) \ + for(vpx_tlv_iter0(itv, ptr, len); vpx_tlv_itern(itv);) + int -VPX_tlv(const struct req *req, int tlv, void **dst, int *len) +VPX_tlv(const struct req *req, int typ, void **dst, int *len) { - uintptr_t *p; - uint16_t *tlv_len_p; - uint16_t l; - char *d; - int ssltlv = 0; + struct vpx_tlv *tlv; + struct vpx_tlv_iter vpi[1], vpi2[1]; + uintptr_t *up; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); + AN(dst); + AN(len); + *dst = NULL; + *len = 0; - if (SES_Get_xport_priv(req->sp, &p) != 0) { - *dst = NULL; + if (SES_Get_proxy_tlv(req->sp, &up) != 0 || *up == 0) return (-1); - } - tlv_len_p = (void *)(*p); - l = *tlv_len_p; - d = (char *)(tlv_len_p + 1); + CAST_OBJ_NOTNULL(tlv, (void*)(*up), VPX_TLV_MAGIC); - if (tlv > PP2_TYPE_SSL && tlv <= PP2_SUBTYPE_SSL_MAX) { - ssltlv = tlv; - tlv = PP2_TYPE_SSL; - } - while (l > sizeof(struct pp2_tlv)) { - uint16_t v_len = vbe16dec(d + 1); - if (d[0] == tlv) { - if (ssltlv) { - char *sd; - int sl; - sd = d + sizeof(struct pp2_tlv) + - sizeof(struct pp2_tlv_ssl); - sl = l - sizeof(struct pp2_tlv) - - sizeof(struct pp2_tlv_ssl); - while (sl > sizeof(struct pp2_tlv)) { - uint16_t subv_len = vbe16dec(sd + 1); - if (sd[0] == ssltlv) { - *dst = sd + 3; - *len = subv_len; - return (0); - } - sd += (subv_len + 3); - sl -= (subv_len + 3); - } - } else { - *dst = d + 3; - *len = v_len; + VPX_TLV_FOREACH(tlv->tlv, tlv->len, vpi) { + if (vpi->t == typ) { + *dst = vpi->p; + *len = vpi->l; + return (0); + } + if (vpi->t != PP2_TYPE_SSL) + continue; + VPX_TLV_FOREACH((char*)vpi->p + 5, vpi->l - 5, vpi2) { + if (vpi2->t == typ) { + *dst = vpi2->p; + *len = vpi2->l; return (0); } } - d += (v_len + 3); - l -= (v_len + 3); } - *dst = NULL; return (-1); } @@ -310,7 +331,6 @@ vpx_proto2(const struct worker *wrk, struct req *req) { int l, hdr_len; uintptr_t *up; - uint16_t *tlv_len_p; uint16_t tlv_len; const uint8_t *p; char *d, *tlv_start; @@ -322,6 +342,8 @@ vpx_proto2(const struct worker *wrk, struct req *req) char pa[VTCP_PORTBUFSIZE]; char hb[VTCP_ADDRBUFSIZE]; char pb[VTCP_PORTBUFSIZE]; + struct vpx_tlv_iter vpi[1], vpi2[1]; + struct vpx_tlv *tlv; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -374,27 +396,6 @@ vpx_proto2(const struct worker *wrk, struct req *req) } l -= 12; d += 12; - break; - case 0x21: - /* IPv6|TCP */ - pfam = AF_INET6; - if (l < 36) { - VSL(SLT_ProxyGarbage, req->sp->vxid, - "PROXY2: Ignoring short IPv6 addresses (%d)", l); - return (0); - } - l -= 36; - d += 36; - break; - default: - /* Ignore proxy header */ - VSL(SLT_ProxyGarbage, req->sp->vxid, - "PROXY2: Ignoring unsupported protocol (0x%02x)", p[13]); - return (0); - } - - switch (pfam) { - case AF_INET: memset(&sin4, 0, sizeof sin4); sin4.sin_family = pfam; @@ -411,7 +412,16 @@ vpx_proto2(const struct worker *wrk, struct req *req) SES_Reserve_client_addr(req->sp, &sa); AN(VSA_Build(sa, &sin4, sizeof sin4)); break; - case AF_INET6: + case 0x21: + /* IPv6|TCP */ + pfam = AF_INET6; + if (l < 36) { + VSL(SLT_ProxyGarbage, req->sp->vxid, + "PROXY2: Ignoring short IPv6 addresses (%d)", l); + return (0); + } + l -= 36; + d += 36; memset(&sin6, 0, sizeof sin6); sin6.sin6_family = pfam; @@ -429,7 +439,10 @@ vpx_proto2(const struct worker *wrk, struct req *req) AN(VSA_Build(sa, &sin6, sizeof sin6)); break; default: - WRONG("Wrong pfam"); + /* Ignore proxy header */ + VSL(SLT_ProxyGarbage, req->sp->vxid, + "PROXY2: Ignoring unsupported protocol (0x%02x)", p[13]); + return (0); } AN(sa); @@ -442,62 +455,36 @@ vpx_proto2(const struct worker *wrk, struct req *req) tlv_start = d; tlv_len = l; - while (l > sizeof(struct pp2_tlv)) { - int el = vbe16dec(d + 1) + 3; - if (el > l) { - VSL(SLT_ProxyGarbage, req->sp->vxid, - "PROXY2: Ignoring TLV"); - return (0); - } - switch (d[0]) { - case PP2_TYPE_CRC32C: - { - uint32_t n_crc32c = vbe32dec(d+3); - *(d+3) = 0; *(d+4) = 0; *(d+5) = 0; *(d+6) = 0; + VPX_TLV_FOREACH(d, l, vpi) { + if (vpi->t == PP2_TYPE_SSL) { + VPX_TLV_FOREACH((char*)vpi->p + 5, vpi->l - 5, vpi2) { + } + vpi->e = vpi2->e; + } else if (vpi->t == PP2_TYPE_CRC32C) { + uint32_t n_crc32c = vbe32dec(vpi->p); + vbe32enc(vpi->p, 0); if (crc32c(p, hdr_len) != n_crc32c) { VSL(SLT_ProxyGarbage, req->sp->vxid, "PROXY2: CRC error"); return (-1); } - break; - } - case PP2_TYPE_SSL: - { - const char *sd; - int sl; - sd = d + sizeof(struct pp2_tlv) + - sizeof(struct pp2_tlv_ssl); - sl = l - sizeof(struct pp2_tlv) - - sizeof(struct pp2_tlv_ssl); - while (sl > sizeof(struct pp2_tlv)) { - int esl = vbe16dec(sd + 1) + 3; - if (esl > sl) { - VSL(SLT_ProxyGarbage, req->sp->vxid, - "PROXY2: Ignoring SSL TLV"); - return (0); - } - sd += esl; - sl -= esl; - } - break; } - } - d += el; - l -= el; } - if (l) { - VSL(SLT_ProxyGarbage, req->sp->vxid, - "PROXY2: header length mismatch"); - return (0); + if (vpi->e != NULL) { + VSL(SLT_ProxyGarbage, req->sp->vxid, "PROXY2: TLV %s", vpi->e); + return (-1); } - if (tlv_len && WS_Reserve(req->sp->ws, 2 + tlv_len)) { - tlv_len_p = (void *)req->sp->ws->f; - *tlv_len_p = tlv_len; - memcpy(req->sp->ws->f + 2, tlv_start, tlv_len); - WS_Release(req->sp->ws, 2 + tlv_len); - SES_Reserve_xport_priv(req->sp, &up); - *up = (uintptr_t)tlv_len_p; + tlv = WS_Alloc(req->sp->ws, sizeof *tlv + tlv_len); + if (tlv == NULL) { + VSL(SLT_ProxyGarbage, req->sp->vxid, + "PROXY2: TLV overflows WS"); + return (-1); } + INIT_OBJ(tlv, VPX_TLV_MAGIC); + tlv->len = tlv_len; + memcpy(tlv->tlv, tlv_start, tlv_len); + SES_Reserve_proxy_tlv(req->sp, &up); + *up = (uintptr_t)tlv; return (0); } diff --git a/bin/varnishtest/tests/o00005.vtc b/bin/varnishtest/tests/o00005.vtc index d40e3538d..96154e82c 100644 --- a/bin/varnishtest/tests/o00005.vtc +++ b/bin/varnishtest/tests/o00005.vtc @@ -31,16 +31,31 @@ varnish v1 -proto "PROXY" -vcl+backend { } } -start +logexpect l1 -v v1 -g raw { + expect * 1000 Begin "sess 0 PROXY" + expect * 1000 Proxy "2 217.70.181.33 60822 95.142.168.34 443" + expect * 1000 Link "req 1001 rxreq" +} -start + client c1 { # PROXY2 with CRC32C TLV - sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a 21 11 00 65" - sendhex "d9 46 b5 21 5f 8e a8 22 ed 96 01 bb 03 00 04 95" - sendhex "03 ee 75 01 00 02 68 32 02 00 0a 68 6f 63 64 65" - sendhex "74 2e 6e 65 74 20 00 3d 01 00 00 00 00 21 00 07" - sendhex "54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24" - sendhex "00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41" - sendhex "45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53" - sendhex "48 41 32 35 36" + sendhex { + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 65 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + 03 00 04 95 03 ee 75 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d + 01 00 00 00 00 + 21 00 07 54 4c 53 76 31 2e 33 + 25 00 05 45 43 32 35 36 + 24 00 0a 52 53 41 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + } txreq rxresp expect resp.status == 200 @@ -57,16 +72,136 @@ client c1 { expect resp.http.cn == "" } -run +varnish v1 -vsl_catchup + +logexpect l1 -wait + +logexpect l1 -v v1 -g raw { + expect * 1003 Begin "sess 0 PROXY" + expect * 1003 ProxyGarbage "PROXY2: CRC error" +} -start + +client c1 { + # PROXY2 with CRC32C TLV and bad checksum + sendhex { + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 65 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + 03 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d + 01 00 00 00 00 + 21 00 07 54 4c 53 76 31 2e 33 + 25 00 05 45 43 32 35 36 + 24 00 0a 52 53 41 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + } + txreq + expect_close +} -run + +varnish v1 -vsl_catchup + +logexpect l1 -wait + +logexpect l1 -v v1 -g raw { + expect * 1004 Begin "sess 0 PROXY" + expect * 1004 ProxyGarbage "PROXY2: TLV Dribble bytes" +} -start + +client c1 { + # PROXY2 with CRC32C TLV and bad checksum + sendhex { + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 67 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + ff 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d + 01 00 00 00 00 + 21 00 07 54 4c 53 76 31 2e 33 + 25 00 05 45 43 32 35 36 + 24 00 0a 52 53 41 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + ff ff + } + txreq + expect_close +} -run + +varnish v1 -vsl_catchup + +logexpect l1 -wait + +logexpect l1 -v v1 -g raw { + expect * 1005 Begin "sess 0 PROXY" + expect * 1005 ProxyGarbage "PROXY2: TLV Length Error" +} -start + +client c1 { + # PROXY2 with CRC32C TLV and bad checksum + sendhex { + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 60 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + ff 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d + 01 00 00 00 00 + 21 00 07 54 4c 53 76 31 2e 33 + 25 00 05 45 43 32 35 36 + 24 00 0a 52 53 41 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + } + txreq + expect_close +} -run + +varnish v1 -vsl_catchup + +logexpect l1 -wait + +logexpect l1 -v v1 -g raw { + expect * 1006 Begin "sess 0 PROXY" + expect * 1006 ProxyGarbage "PROXY2: TLV Length Error" +} -start + client c1 { # PROXY2 with CRC32C TLV and bad checksum - sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a 21 11 00 65" - sendhex "d9 46 b5 21 5f 8e a8 22 ed 96 01 bb 03 00 04 95" - sendhex "03 ee 75 01 00 02 68 32 02 00 0a 68 6f 63 64 65" - sendhex "74 2e 6e 65 74 20 00 3d 01 00 00 00 00 21 00 07" - sendhex "54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24" - sendhex "00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41" - sendhex "45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53" - sendhex "48 41 32 35 35" + sendhex { + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 65 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + ff 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3c + 01 00 00 00 00 + 21 00 07 54 4c 53 76 31 2e 33 + 25 00 05 45 43 32 35 36 + 24 00 0a 52 53 41 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + } txreq expect_close } -run + +varnish v1 -vsl_catchup + +logexpect l1 -wait + diff --git a/include/tbl/sess_attr.h b/include/tbl/sess_attr.h index 6b83fb3ec..5276a1861 100644 --- a/include/tbl/sess_attr.h +++ b/include/tbl/sess_attr.h @@ -39,7 +39,7 @@ SESS_ATTR(CLIENT_ADDR, client_addr, struct suckaddr, vsa_suckaddr_len) SESS_ATTR(SERVER_ADDR, server_addr, struct suckaddr, vsa_suckaddr_len) SESS_ATTR(CLIENT_IP, client_ip, char, -1) SESS_ATTR(CLIENT_PORT, client_port, char, -1) -SESS_ATTR(XPORT_PRIV, xport_priv, uintptr_t, sizeof(uintptr_t)) +SESS_ATTR(PROXY_TLV, proxy_tlv, uintptr_t, sizeof(uintptr_t)) SESS_ATTR(PROTO_PRIV, proto_priv, uintptr_t, sizeof(uintptr_t)) #undef SESS_ATTR From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] af6408c1f Unused #include Message-ID: <20180816085240.0619098DF8@lists.varnish-cache.org> commit af6408c1f106d6de6894d9fb9bcf68912ef828c2 Author: Poul-Henning Kamp Date: Tue Apr 10 08:58:29 2018 +0000 Unused #include diff --git a/lib/libvmod_proxy/vmod_proxy.c b/lib/libvmod_proxy/vmod_proxy.c index 8c6973c1a..fa7b9617e 100644 --- a/lib/libvmod_proxy/vmod_proxy.c +++ b/lib/libvmod_proxy/vmod_proxy.c @@ -35,7 +35,6 @@ #include "cache/cache.h" #include "vend.h" -#include "vcl.h" #include "proxy/cache_proxy.h" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] 07e80a0f7 Attempt to stabilize test g00005 by making the test do what it purports to say on the tin, and by removing the quantum-test it trips over. Message-ID: <20180816085240.2F08F98E13@lists.varnish-cache.org> commit 07e80a0f7f6f1bd6bb9461f82716c827af4a710e Author: Poul-Henning Kamp Date: Tue Apr 10 11:05:30 2018 +0000 Attempt to stabilize test g00005 by making the test do what it purports to say on the tin, and by removing the quantum-test it trips over. diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index aee17d3dd..7cb317c59 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -315,21 +315,18 @@ vdp_gunzip(struct req *req, enum vdp_action act, void **priv, http_Unset(req->resp, H_Content_Encoding); req->resp_len = -1; - if (req->objcore->boc != NULL) - return (0); /* No idea about length (yet) */ p = ObjGetAttr(req->wrk, req->objcore, OA_GZIPBITS, &dl); - if (p == NULL || dl != 32) - return (0); /* No OA_GZIPBITS yet */ - - u = vbe64dec(p + 24); - /* - * If the size is non-zero AND we are the top - * VDP (ie: no ESI), we know what size the output will be. - */ - if (u != 0 && VTAILQ_FIRST(&req->vdc->vdp)->vdp == &VDP_gunzip) - req->resp_len = u; - + if (p != NULL || dl == 32) { + u = vbe64dec(p + 24); + /* + * If the size is non-zero AND we are the top VDP + * (ie: no ESI), we know what size the output will be. + */ + if (u != 0 && + VTAILQ_FIRST(&req->vdc->vdp)->vdp == &VDP_gunzip) + req->resp_len = u; + } return (0); } diff --git a/bin/varnishtest/tests/g00005.vtc b/bin/varnishtest/tests/g00005.vtc index 9eacb10b1..24b3b6071 100644 --- a/bin/varnishtest/tests/g00005.vtc +++ b/bin/varnishtest/tests/g00005.vtc @@ -3,7 +3,17 @@ varnishtest "test gunzip for client + Range" server s1 -repeat 3 { rxreq expect req.http.accept-encoding == "gzip" - txresp -gzipbody FOOBARBARF + txresp -nolen -hdr "Transfer-encoding: chunked" \ + -hdr "Content-encoding: gzip" + delay 1 + # Compressed "FOOBARBARF" + sendhex { + 31 43 0d 0a + 1f 8b 08 00 75 96 cc 5a 02 03 73 f3 f7 77 72 0c + 02 22 37 00 06 8e 8c 83 0a 00 00 00 + 0d 0a + 30 0d 0a 0d 0a + } } -start varnish v1 -cliok "param.set http_gzip_support true" -vcl+backend { @@ -21,33 +31,49 @@ client c1 { expect resp.status == 200 expect resp.bodylen == "10" expect resp.http.content-encoding == +} -run + +varnish v1 -vsl_catchup +client c1 { txreq -hdr "Accept-encoding: gzip;q=0.1" rxresp expect resp.http.content-encoding == "gzip" gunzip expect resp.bodylen == "10" +} -run - # This delay attempts to ensure that the busyobj - # is completed before we attempt the range request - delay 1 +varnish v1 -vsl_catchup + +# This delay attempts to ensure that the busyobj +# is completed before we attempt the range request +delay 2 +client c1 { txreq -hdr "Range: bytes=3-5" rxresp expect resp.status == 206 expect resp.http.content-encoding == "" expect resp.bodylen == "3" expect resp.body == "BAR" +} -run +varnish v1 -vsl_catchup + +client c1 { txreq -url "/nostreamcachemiss" -hdr "Range: bytes=3-5" rxresp expect resp.status == 206 expect resp.http.content-encoding == "" expect resp.bodylen == "3" expect resp.body == "BAR" +} -run + +varnish v1 -vsl_catchup - # simple cache miss no gunzip - txreq -url "/2" -hdr "Range: bytes=3-5" -hdr "Accept-Encoding: gzip" +client c1 { + # simple cache miss, no stream, no gunzip + txreq -url "/nostream2" -hdr "Range: bytes=3-5" -hdr "Accept-Encoding: gzip" rxresp expect resp.status == 206 expect resp.http.content-encoding == "gzip" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] af1b06125 Duh! && not ||. Message-ID: <20180816085240.54AC098E3B@lists.varnish-cache.org> commit af1b061258f24fc4566a590269654c61a2506b94 Author: Poul-Henning Kamp Date: Tue Apr 10 12:54:38 2018 +0000 Duh! && not ||. Spotted by: fgs diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 7cb317c59..72a86dd99 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -317,7 +317,7 @@ vdp_gunzip(struct req *req, enum vdp_action act, void **priv, req->resp_len = -1; p = ObjGetAttr(req->wrk, req->objcore, OA_GZIPBITS, &dl); - if (p != NULL || dl == 32) { + if (p != NULL && dl == 32) { u = vbe64dec(p + 24); /* * If the size is non-zero AND we are the top VDP From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] 04b08d879 Add a basic stack overflow detection heuristic Message-ID: <20180816085240.7AE6F98E53@lists.varnish-cache.org> commit 04b08d8793f0b856d78d33a84085e594f093ab78 Author: Nils Goroll Date: Tue Apr 10 16:12:24 2018 +0200 Add a basic stack overflow detection heuristic Yes, I know, this is far from perfect, but it does not require any changes outside the signal handler and will hopefully simplify error report handling significantly. Ref #2643 diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index ad7e31249..fe8cdb34d 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -235,17 +235,36 @@ child_signal_handler(int s, siginfo_t *si, void *c) { char buf[1024]; struct sigaction sa; + struct req *req; + const char *a, *p, *info = NULL; (void)c; - /* Don't come back */ memset(&sa, 0, sizeof sa); sa.sa_handler = SIG_DFL; (void)sigaction(SIGSEGV, &sa, NULL); (void)sigaction(SIGABRT, &sa, NULL); - bprintf(buf, "Signal %d (%s) received at %p si_code %d", - s, strsignal(s), si->si_addr, si->si_code); + while (s == SIGSEGV) { + req = THR_GetRequest(); + if (req == NULL || req->wrk == NULL) + break; + a = TRUST_ME(si->si_addr); + p = TRUST_ME(req->wrk); + p += sizeof *req->wrk; + // rough safe estimate - top of stack + if (a > p + cache_param->wthread_stacksize) + break; + if (a < p - 2 * cache_param->wthread_stacksize) + break; + info = "\nTHIS PROBABLY IS A STACK OVERFLOW - " + "check thread_pool_stack parameter"; + break; + } + bprintf(buf, "Signal %d (%s) received at %p si_code %d%s", + s, strsignal(s), si->si_addr, si->si_code, + info ? info : ""); + VAS_Fail(__func__, __FILE__, __LINE__, diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 2a9c75d70..2c0ad150f 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -96,6 +96,7 @@ WRK_BgThread(pthread_t *thr, const char *name, bgthread_t *func, void *priv) static void WRK_Thread(struct pool *qp, size_t stacksize, unsigned thread_workspace) { + // child_signal_handler stack overflow check uses struct worker addr struct worker *w, ww; struct VSC_main ds; unsigned char ws[thread_workspace]; diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc index 4b05a8f88..c70158e68 100644 --- a/bin/varnishtest/tests/c00057.vtc +++ b/bin/varnishtest/tests/c00057.vtc @@ -39,6 +39,8 @@ client c1 { expect_close } -run +varnish v1 -cliexpect "STACK OVERFLOW" "panic.show" + varnish v1 -cliok "panic.clear" # Also check without the handler @@ -51,3 +53,31 @@ client c1 { } -run varnish v1 -expectexit 0x20 + +#################### + +varnish v2 \ + -arg "-p feature=+no_coredump" \ + -arg "-p vcc_allow_inline_c=true" \ + -vcl+backend { + + C{ + #include + }C + + sub vcl_recv { C{ + int *i = (void *)VRT_GetHdr; + *i = 42; + }C } +} -start + +client c2 -connect ${v2_sock} { + txreq + expect_close +} -run + +varnish v2 -cliexpect "Segmentation fault" "panic.show" + +varnish v2 -cliok "panic.clear" + +varnish v2 -expectexit 0x20 From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] 628177986 Also expect special Solar-ish uppercause Faults Message-ID: <20180816085240.A064298E7F@lists.varnish-cache.org> commit 62817798663db84cebea0d00610ba0ab70864820 Author: Nils Goroll Date: Tue Apr 10 16:37:59 2018 +0200 Also expect special Solar-ish uppercause Faults Ref #2643 diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc index c70158e68..f33a8bde6 100644 --- a/bin/varnishtest/tests/c00057.vtc +++ b/bin/varnishtest/tests/c00057.vtc @@ -76,7 +76,7 @@ client c2 -connect ${v2_sock} { expect_close } -run -varnish v2 -cliexpect "Segmentation fault" "panic.show" +varnish v2 -cliexpect "Segmentation [fF]ault" "panic.show" varnish v2 -cliok "panic.clear" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] b5033c59a Use an anonymous struct to pass the argstruct to vmod functions Message-ID: <20180816085240.C8C5098EA2@lists.varnish-cache.org> commit b5033c59a8b6989a1f0fc255bacada4226022fa4 Author: Nils Goroll Date: Tue Apr 10 17:11:42 2018 +0200 Use an anonymous struct to pass the argstruct to vmod functions ... to save stack space Fixes #2643 diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 032a6e939..08977af28 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -467,7 +467,6 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, const struct vjsn_val *vv, *vvp; const char *sa; char ssa[64]; - char ssa2[64]; int n; CAST_OBJ_NOTNULL(vv, priv, VJSN_VAL_MAGIC); @@ -481,10 +480,6 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, sa = vv->value; if (*sa == '\0') { sa = NULL; - } else { - bprintf(ssa, "args_%u", tl->unique++); - VSB_printf(tl->curproc->prologue, " %s %s;\n", sa, ssa); - sa = ssa; } vv = VTAILQ_NEXT(vv, list); SkipToken(tl, '('); @@ -572,27 +567,28 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, } if (sa != NULL) - e1 = vcc_mk_expr(rfmt, "%s(ctx%s,\v+(\n", cfunc, extra); + e1 = vcc_mk_expr(rfmt, "%s(ctx%s,\v+ &(%s){\n", + cfunc, extra, sa); else e1 = vcc_mk_expr(rfmt, "%s(ctx%s\v+", cfunc, extra); n = 0; VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) { n++; - if (fa->optional) - VSB_printf(tl->curproc->prologue, - " %s.valid_%s = %d;\n", sa, fa->name, fa->avail); + if (fa->optional) { + bprintf(ssa, "\v1.valid_%s = %d,\n", + fa->name, fa->avail); + e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL); + } if (fa->result == NULL && fa->type == ENUM && fa->val != NULL) vcc_do_enum(tl, fa, strlen(fa->val), fa->val); if (fa->result == NULL && fa->val != NULL) fa->result = vcc_mk_expr(fa->type, "%s", fa->val); if (fa->result != NULL && sa != NULL) { if (fa->name && *fa->name != '\0') - bprintf(ssa2, "\v1%s.%s = \v2,\n", - sa, fa->name); + bprintf(ssa, "\v1.%s = \v2,\n", fa->name); else - bprintf(ssa2, "\v1%s.arg%d = \v2,\n", - sa, n); - e1 = vcc_expr_edit(tl, e1->fmt, ssa2, e1, fa->result); + bprintf(ssa, "\v1.arg%d = \v2,\n", n); + e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, fa->result); } else if (fa->result != NULL) { e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2", e1, fa->result); @@ -604,8 +600,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, free(fa); } if (sa != NULL) { - bprintf(ssa2, "\v1&%s\v-\n))", sa); - *e = vcc_expr_edit(tl, e1->fmt, ssa2, e1, NULL); + *e = vcc_expr_edit(tl, e1->fmt, "\v1\n})\v-", e1, NULL); } else { *e = vcc_expr_edit(tl, e1->fmt, "\v1\n)\v-", e1, NULL); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:40 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:40 +0000 (UTC) Subject: [6.0] c34255fa4 Only check errno if write(2) failed. Message-ID: <20180816085240.F032298EC4@lists.varnish-cache.org> commit c34255fa4de70b31fb35eca827880683b2bb78b0 Author: Poul-Henning Kamp Date: Wed Apr 11 07:18:36 2018 +0000 Only check errno if write(2) failed. Hopefully this... Fixes #2605 diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index edb9907fd..c88fffdb6 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -271,7 +271,8 @@ http1_minimal_response(struct req *req, uint16_t status) if (wl > 0) req->acct.resp_hdrbytes += wl; if (wl != l) { - VTCP_Assert(1); + if (wl < 0) + VTCP_Assert(1); if (!req->doclose) req->doclose = SC_REM_CLOSE; return (-1); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:41 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:41 +0000 (UTC) Subject: [6.0] 5664571e0 No idea how I overlooked that wl was unsigned. Message-ID: <20180816085241.2531998EE1@lists.varnish-cache.org> commit 5664571e0bbfe291799a516d84acaa534bb9dd98 Author: Poul-Henning Kamp Date: Wed Apr 11 08:27:43 2018 +0000 No idea how I overlooked that wl was unsigned. Doesn't change the logic however. diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index c88fffdb6..650690950 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -247,7 +247,7 @@ http1_reembark(struct worker *wrk, struct req *req) static int v_matchproto_(vtr_minimal_response_f) http1_minimal_response(struct req *req, uint16_t status) { - size_t wl, l; + ssize_t wl, l; char buf[80]; const char *reason; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:41 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:41 +0000 (UTC) Subject: [6.0] d48317b36 handle workspace overflow in V1F_Setup_Fetch() Message-ID: <20180816085241.4525998EFB@lists.varnish-cache.org> commit d48317b3676d6fb4ccff452bbb9fe59aa3fa76e7 Author: Nils Goroll Date: Wed Apr 11 12:08:09 2018 +0200 handle workspace overflow in V1F_Setup_Fetch() Ref #2645 but cannot be the cause because workspace is just not overflowed diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 1a7702120..27bf52101 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -216,7 +216,11 @@ V1F_FetchRespHdr(struct busyobj *bo) assert(bo->vfc->resp == bo->beresp); if (bo->htc->body_status != BS_NONE && bo->htc->body_status != BS_ERROR) - (void)V1F_Setup_Fetch(bo->vfc, bo->htc); + if (V1F_Setup_Fetch(bo->vfc, bo->htc)) { + VSLb(bo->vsl, SLT_FetchError, "overflow"); + htc->doclose = SC_RX_OVERFLOW; + return (-1); + } return (0); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:41 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:41 +0000 (UTC) Subject: [6.0] 1d2d84643 Report cursor position in screen-dump, and add "-expect-cursor" Message-ID: <20180816085241.707F198F1D@lists.varnish-cache.org> commit 1d2d846433c3cb970f67d479b2ed1edbca4b8796 Author: Poul-Henning Kamp Date: Wed Apr 11 19:34:02 2018 +0000 Report cursor position in screen-dump, and add "-expect-cursor" diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index affa7472c..52736fda7 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -55,10 +55,14 @@ process p4 -write "\x1b[H\x1b[2J1\x1b[79C2\x08>\x1b[25;1H3\x1b[25;80H" process p4 -write "4\x08>\x1b[A\x1b[Cv\x1b[22A^\x1b[79D^\x1b[;2H<\n\n\n\n" process p4 -write "\n\n\n\n\n\n\n\n\x1b[B\x1b[11B\x08<\x1b[24;Hv\x1b[12;1H" process p4 -write "111111112222222333333\x0d\x0a111111112" -process p4 -write "222222333333\x0d\x0a111111112222222333" -process p4 -write "333\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" +process p4 -write "222222333333\x0d\x0a111111112222222333333 UTF8: " +process p4 -writehex {c2 a2 20 e2 82 ac 20 f0 9f 90 b0} +process p4 -write "\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" process p4 -write ";12H\x1b[K\x1b[13;12H\x1b[0K\x1b[14;12H\x1b[1K\x1b" process p4 -write "[15;12H\x1b[2K\x1b[3;1Hline3 <\x0d\x0a" -process p4 -need-bytes 252 -expect-text 3 1 "line3 <" -process p4 -screen_dump -stop +process p4 -need-bytes 270 -expect-text 3 1 "line3 <" +process p4 -expect-cursor 4 1 +process p4 -expect-cursor 4 0 +process p4 -expect-cursor 0 1 +process p4 -screen-dump -stop diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index be763239a..a3f920d8a 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -205,9 +205,13 @@ static void term_screen_dump(const struct process *pp) { int i; + const teken_pos_t *pos; for (i = 0; i < pp->nlin; i++) vtc_dump(pp->vl, 3, "screen", pp->vram[i], pp->ncol); + pos = teken_get_cursor(pp->tek); + vtc_log(pp->vl, 3, "Cursor at line %d column %d", + pos->tp_row + 1, pos->tp_col + 1); } static void @@ -312,6 +316,23 @@ term_expect_text(struct process *pp, vtc_log(pp->vl, 4, "found expected text at %d,%d: '%s'", y, x, pat); } +static void +term_expect_cursor(struct process *pp, const char *lin, const char *col) +{ + int x, y; + const teken_pos_t *pos; + + pos = teken_get_cursor(pp->tek); + y = strtoul(lin, NULL, 0); + x = strtoul(col, NULL, 0); + if (y != 0 && (y-1) != pos->tp_row) + vtc_fatal(pp->vl, "Cursor on line %d (expected %d)", + pos->tp_row + 1, y); + if (x != 0 && (x-1) != pos->tp_col) + vtc_fatal(pp->vl, "Cursor in column %d (expected %d)", + pos->tp_col + 1, y); +} + /********************************************************************** * Allocate and initialize a process */ @@ -968,7 +989,15 @@ cmd_process(CMD_ARGS) av += 3; continue; } - if (!strcmp(*av, "-screen_dump")) { + if (!strcmp(*av, "-expect-cursor")) { + AN(av[1]); + AN(av[2]); + term_expect_cursor(p, av[1], av[2]); + av += 2; + continue; + } + if (!strcmp(*av, "-screen_dump") || + !strcmp(*av, "-screen-dump")) { term_screen_dump(p); continue; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:41 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:41 +0000 (UTC) Subject: [6.0] 571da776e Test form-feed Message-ID: <20180816085241.9DD8098F41@lists.varnish-cache.org> commit 571da776e276a950c54e8c24e9bc583e88d40216 Author: Poul-Henning Kamp Date: Thu Apr 12 06:37:37 2018 +0000 Test form-feed diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index 52736fda7..f5ef79140 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -51,6 +51,8 @@ process p4 -hexdump {stty raw -echo; echo "*" ; sleep 2 ; cat} -start process p4 -expect-text 0 0 "*" +process p4 -write "\x1b[H\x1b[2Jzzzzzzz" +process p4 -write "\x0c1\x1b[79C2\x08>\x1b[25;1H3\x1b[25;80H" process p4 -write "\x1b[H\x1b[2J1\x1b[79C2\x08>\x1b[25;1H3\x1b[25;80H" process p4 -write "4\x08>\x1b[A\x1b[Cv\x1b[22A^\x1b[79D^\x1b[;2H<\n\n\n\n" process p4 -write "\n\n\n\n\n\n\n\n\x1b[B\x1b[11B\x08<\x1b[24;Hv\x1b[12;1H" @@ -61,7 +63,7 @@ process p4 -write "\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" process p4 -write ";12H\x1b[K\x1b[13;12H\x1b[0K\x1b[14;12H\x1b[1K\x1b" process p4 -write "[15;12H\x1b[2K\x1b[3;1Hline3 <\x0d\x0a" -process p4 -need-bytes 270 -expect-text 3 1 "line3 <" +process p4 -need-bytes 310 -expect-text 3 1 "line3 <" process p4 -expect-cursor 4 1 process p4 -expect-cursor 4 0 process p4 -expect-cursor 0 1 From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:41 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:41 +0000 (UTC) Subject: [6.0] 76abfa750 Clarify things for Coverity Message-ID: <20180816085241.BDFFB98F5A@lists.varnish-cache.org> commit 76abfa7507b504d21641540135c817dd92b2d8b1 Author: Poul-Henning Kamp Date: Thu Apr 12 08:07:00 2018 +0000 Clarify things for Coverity diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 73f42b879..663a363b1 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -388,6 +388,7 @@ haproxy_build_backends(const struct haproxy *h, const char *vsb_data) if (err != NULL) vtc_fatal(h->vl, "Create listen socket failed: %s", err); + assert(sock > 0); VTCP_myname(sock, addr, sizeof addr, port, sizeof port); bprintf(buf, "%s_%s", h->name, p); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:41 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:41 +0000 (UTC) Subject: [6.0] 661a350b7 Redo struct h2_sess allocation/workspace snapshot Message-ID: <20180816085241.E30A998F77@lists.varnish-cache.org> commit 661a350b7b99f5bf9d96b8464b25801da70822af Author: Dag Haavi Finstad Date: Thu Apr 12 13:42:30 2018 +0200 Redo struct h2_sess allocation/workspace snapshot Instead of allocating struct h2_sess out of the same workspace that is used as our rxbuffer, we rather keep it on the stack in h2_new_session. If the size of the initial h/2 request payload is close to half the size of the workspace, we would end up exhausting the workspace in HTC_RxInit after allocating our h2sess struct. Spotted by Federico G. Schwindt Fixes: #2619 diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index 799d10903..e34f8240a 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -93,12 +93,11 @@ h2_local_settings(struct h2_settings *h2s) * WS, VSL, HTC &c, but rather than implement all that stuff over, we * grab an actual struct req, and mirror the relevant fields into * struct h2_sess. - * To make things really incestuous, we allocate the h2_sess on - * the WS of that "Session ReQuest". */ static struct h2_sess * -h2_new_sess(const struct worker *wrk, struct sess *sp, struct req *srq) +h2_init_sess(const struct worker *wrk, struct sess *sp, + struct h2_sess *h2s, struct req *srq) { uintptr_t *up; struct h2_sess *h2; @@ -112,7 +111,7 @@ h2_new_sess(const struct worker *wrk, struct sess *sp, struct req *srq) if (srq == NULL) srq = Req_New(wrk, sp); AN(srq); - h2 = WS_Alloc(srq->ws, sizeof *h2); + h2 = h2s; AN(h2); INIT_OBJ(h2, H2_SESS_MAGIC); h2->srq = srq; @@ -331,9 +330,9 @@ h2_new_session(struct worker *wrk, void *arg) { struct req *req; struct sess *sp; + struct h2_sess h2s; struct h2_sess *h2; struct h2_req *r2, *r22; - uintptr_t wsp; int again; uint8_t settings[48]; size_t l; @@ -347,8 +346,8 @@ h2_new_session(struct worker *wrk, void *arg) assert (req->err_code == H2_PU_MARKER || req->err_code == H2_OU_MARKER); - h2 = h2_new_sess(wrk, sp, req->err_code == H2_PU_MARKER ? req : NULL); - wsp = WS_Snapshot(h2->ws); + h2 = h2_init_sess(wrk, sp, &h2s, + req->err_code == H2_PU_MARKER ? req : NULL); h2->req0 = h2_new_req(wrk, h2, 0, NULL); if (req->err_code == H2_OU_MARKER && !h2_ou_session(wrk, h2, req)) { @@ -359,6 +358,7 @@ h2_new_session(struct worker *wrk, void *arg) } assert(HTC_S_COMPLETE == H2_prism_complete(h2->htc)); HTC_RxPipeline(h2->htc, h2->htc->rxbuf_b + sizeof(H2_prism)); + WS_Reset(h2->ws, 0); HTC_RxInit(h2->htc, h2->ws); AN(h2->ws->r); VSLb(h2->vsl, SLT_Debug, "H2: Got pu PRISM"); @@ -380,7 +380,7 @@ h2_new_session(struct worker *wrk, void *arg) h2->cond = &wrk->cond; while (h2_rxframe(wrk, h2)) { - WS_Reset(h2->ws, wsp); + WS_Reset(h2->ws, 0); HTC_RxInit(h2->htc, h2->ws); if (WS_Overflowed(h2->ws)) { VSLb(h2->vsl, SLT_Debug, "H2: Empty Rx Workspace"); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:42 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:42 +0000 (UTC) Subject: [6.0] 30c721188 Plug some leaks Message-ID: <20180816085242.2F7EA98F93@lists.varnish-cache.org> commit 30c7211881a16003c385a964e5308b877b12a4aa Author: Federico G. Schwindt Date: Fri Apr 13 10:16:32 2018 +0100 Plug some leaks diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index d4e45c777..c6c58979e 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -167,7 +167,7 @@ macro_undef(struct vtclog *vl, const char *instance, const char *name) VTAILQ_REMOVE(¯o_list, m, list); free(m->name); free(m->val); - free(m); + FREE_OBJ(m); } AZ(pthread_mutex_unlock(¯o_mtx)); } diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 663a363b1..8d4118fe5 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -56,7 +56,7 @@ struct haproxy { struct vtclog *vl; VTAILQ_ENTRY(haproxy) list; - char *filename; + const char *filename; struct vsb *args; int opt_worker; int opt_daemon; @@ -72,7 +72,7 @@ struct haproxy { int expect_signal; int its_dead_jim; - const char *cli_fn; + char *cli_fn; char *workdir; struct vsb *msgs; @@ -152,7 +152,7 @@ haproxy_new(const char *name) h->filename = getenv(HAPROXY_PROGRAM_ENV_VAR); if (h->filename == NULL) - REPLACE(h->filename, "haproxy"); + h->filename = "haproxy"; bprintf(buf, "${tmpdir}/%s", name); vsb = macro_expand(h->vl, buf); @@ -196,6 +196,9 @@ haproxy_delete(struct haproxy *h) free(h->name); free(h->workdir); + free(h->cli_fn); + free(h->cfg_fn); + free(h->pid_fn); VSB_destroy(&h->args); /* XXX: MEMLEAK (?) */ diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 0634d6669..2c0b761b4 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -884,6 +884,7 @@ http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, } } else if (!strcmp(*av, "-bodylen")) { assert(body == nullbody); + free(body); body = synth_body(av[1], 0); bodylen = strlen(body); av++; @@ -895,13 +896,16 @@ http_tx_parse_args(char * const *av, struct vtclog *vl, struct http *hp, av++; } else if (!strcmp(*av, "-gziplen")) { assert(body == nullbody); + free(body); b = synth_body(av[1], 1); gzip_body(hp, b, &body, &bodylen); + free(b); VSB_printf(hp->vsb, "Content-Encoding: gzip%s", nl); // vtc_hexdump(hp->vl, 4, "gzip", (void*)body, bodylen); av++; } else if (!strcmp(*av, "-gzipbody")) { assert(body == nullbody); + free(body); gzip_body(hp, av[1], &body, &bodylen); VSB_printf(hp->vsb, "Content-Encoding: gzip%s", nl); // vtc_hexdump(hp->vl, 4, "gzip", (void*)body, bodylen); @@ -1911,7 +1915,8 @@ http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, free(hp->rxbuf); free(hp->rem_ip); free(hp->rem_port); - free(hp); + free(hp->rem_path); + FREE_OBJ(hp); return (retval); } diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index cbb3c07b6..735b747fa 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -191,6 +191,7 @@ logexp_delete(struct logexp *le) AZ(le->vslq); logexp_delete_tests(le); free(le->name); + free(le->vname); free(le->query); VSM_Destroy(&le->vsm); FREE_OBJ(le); diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index a3f920d8a..af6da006a 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -386,6 +386,7 @@ process_new(const char *name) static void process_delete(struct process *p) { + int i; CHECK_OBJ_NOTNULL(p, PROCESS_MAGIC); AZ(pthread_mutex_destroy(&p->mtx)); @@ -401,6 +402,10 @@ process_delete(struct process *p) * to the test's tmpdir. */ + for (i = 0; i < p->nlin; i++) + free(p->vram[i]); + free(p->vram); + /* XXX: MEMLEAK (?) */ FREE_OBJ(p); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:42 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:42 +0000 (UTC) Subject: [6.0] 688e657a6 Whitespace and style OCD Message-ID: <20180816085242.6799B98FB3@lists.varnish-cache.org> commit 688e657a62d91ee21172d4fe29be2466e34689dd Author: Federico G. Schwindt Date: Fri Apr 13 10:23:21 2018 +0100 Whitespace and style OCD diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c index 25bdfda24..c66b8a2cd 100644 --- a/bin/varnishtest/vtc_barrier.c +++ b/bin/varnishtest/vtc_barrier.c @@ -277,8 +277,7 @@ barrier_cond_sync(struct barrier *b, struct vtclog *vl) if (++b->waiters == b->expected) { vtc_log(vl, 4, "Barrier(%s) wake %u", b->name, b->expected); AZ(pthread_cond_broadcast(&b->cond)); - } - else { + } else { vtc_log(vl, 4, "Barrier(%s) wait %u of %u", b->name, b->waiters, b->expected); AZ(pthread_cond_wait(&b->cond, &b->mtx)); diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 2c0b761b4..db07d42c9 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -1901,8 +1901,7 @@ http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, VTCP_hisname(sock, hp->rem_ip, VTCP_ADDRBUFSIZE, hp->rem_port, VTCP_PORTBUFSIZE); hp->rem_path = NULL; - } - else { + } else { strcpy(hp->rem_ip, "0.0.0.0"); strcpy(hp->rem_port, "0"); hp->rem_path = strdup(addr); diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index af6da006a..b05d0ce28 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -730,9 +730,8 @@ process_kill(struct process *p, const char *sig) if (kill(-pid, j) < 0) vtc_fatal(p->vl, "Failed to send signal %d (%s)", j, strerror(errno)); - else { + else vtc_log(p->vl, 4, "Sent signal %d", j); - } } /********************************************************************** diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 987eb9829..33e2aa6a2 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -283,7 +283,7 @@ Emit_UDS_Path(struct vcc *tl, const struct token *t_path, const char *errid) vcc_ErrWhere(tl, t_path); return; } - if (! S_ISSOCK(st.st_mode)) { + if (!S_ISSOCK(st.st_mode)) { VSB_printf(tl->sb, "%s: Not a socket:\n", errid); vcc_ErrWhere(tl, t_path); return; diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c index 17b0da291..75dda136b 100644 --- a/lib/libvmod_debug/vmod_debug_dyn.c +++ b/lib/libvmod_debug/vmod_debug_dyn.c @@ -200,7 +200,7 @@ dyn_uds_init(VRT_CTX, struct xyzzy_debug_dyn_uds *uds, VCL_STRING path) VRT_fail(ctx, "Cannot stat path %s: %s", path, strerror(errno)); return (-1); } - if (! S_ISSOCK(st.st_mode)) { + if (!S_ISSOCK(st.st_mode)) { VRT_fail(ctx, "%s is not a socket", path); return (-1); } diff --git a/lib/libvmod_unix/cred_compat.h b/lib/libvmod_unix/cred_compat.h index 843793a75..cd4fd7437 100644 --- a/lib/libvmod_unix/cred_compat.h +++ b/lib/libvmod_unix/cred_compat.h @@ -95,7 +95,7 @@ get_ids(int fd, uid_t *uid, gid_t *gid) priv_set_t *priv = NULL; errno = 0; - if (! priv_ineffect(PRIV_PROC_INFO)) { + if (!priv_ineffect(PRIV_PROC_INFO)) { priv = priv_proc_info; if (setppriv(PRIV_ON, PRIV_EFFECTIVE, priv)) return (CREDS_FAIL); diff --git a/lib/libvmod_unix/vmod_unix.c b/lib/libvmod_unix/vmod_unix.c index f51c10883..59bbb2d8e 100644 --- a/lib/libvmod_unix/vmod_unix.c +++ b/lib/libvmod_unix/vmod_unix.c @@ -94,7 +94,7 @@ vmod_##func(VRT_CTX) \ } \ \ sp = get_sp(ctx); \ - if (! sp->listen_sock->uds) { \ + if (!sp->listen_sock->uds) { \ ERRNOTUDS(ctx); \ return (-1); \ } \ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:42 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:42 +0000 (UTC) Subject: [6.0] b6c26cc52 Fix ASAN compilation under macaos Message-ID: <20180816085242.9718198FC2@lists.varnish-cache.org> commit b6c26cc529a62f80e2e5f28f18aa27edb8346816 Author: Federico G. Schwindt Date: Fri Apr 13 10:49:27 2018 +0100 Fix ASAN compilation under macaos diff --git a/configure.ac b/configure.ac index 2e25adf05..17c6f17c9 100644 --- a/configure.ac +++ b/configure.ac @@ -280,7 +280,11 @@ AC_ARG_ENABLE(msan, if test "x$UBSAN_FLAGS$TSAN_FLAGS$ASAN_FLAGS$MSAN_FLAGS" != "x"; then SAN_CFLAGS="-D__SANITIZER=1 ${UBSAN_FLAGS} ${TSAN_FLAGS} ${ASAN_FLAGS} ${MSAN_FLAGS} -fPIC -fPIE -fno-omit-frame-pointer" - SAN_LDFLAGS="${UBSAN_FLAGS} ${TSAN_FLAGS} ${ASAN_FLAGS} ${MSAN_FLAGS} -pie" + SAN_LDFLAGS="${UBSAN_FLAGS} ${TSAN_FLAGS} ${ASAN_FLAGS} ${MSAN_FLAGS}" + save_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} -Werror=unused-command-line-argument" + AX_CHECK_LINK_FLAG([-pie], [SAN_LDFLAGS="${SAN_LDFLAGS} -pie"]) + CFLAGS="${save_CFLAGS}" case $CC in gcc*) SAN_CFLAGS="${SAN_CFLAGS} -fuse-ld=gold" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:42 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:42 +0000 (UTC) Subject: [6.0] b977bd2aa Exercise the CONS25 code. Message-ID: <20180816085242.D261698FD7@lists.varnish-cache.org> commit b977bd2aa2274773842d412d61d429a4e024d9e7 Author: Poul-Henning Kamp Date: Sat Apr 14 07:09:21 2018 +0000 Exercise the CONS25 code. diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index f5ef79140..a79ceed8b 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -41,15 +41,14 @@ shell -exit 77 -expect {TEST _.vtc skipped} { exec varnishtest -v _.vtc || true } -process p1 "ps -lw | grep '[p][s]' ; tty ; sleep 1" -run -screen_dump +process p1 "ps -lw | grep '[p][s]' ; tty ; echo @" -start +process p1 -expect-text 0 0 {@} -screen_dump -wait -process p2 "stty -a ; sleep 1" -run -screen_dump +process p2 "stty -a ; echo '*'" -start +process p2 -expect-text 0 0 {*} -screen_dump -wait -process p3 "stty raw -echo ; stty -a ; sleep 1" -run -screen_dump - -process p4 -hexdump {stty raw -echo; echo "*" ; sleep 2 ; cat} -start - -process p4 -expect-text 0 0 "*" +process p4 -hexdump {stty raw -echo; stty -a ; echo "*" ; cat} -start +process p4 -expect-text 0 0 "*" -screen_dump process p4 -write "\x1b[H\x1b[2Jzzzzzzz" process p4 -write "\x0c1\x1b[79C2\x08>\x1b[25;1H3\x1b[25;80H" @@ -67,4 +66,28 @@ process p4 -need-bytes 310 -expect-text 3 1 "line3 <" process p4 -expect-cursor 4 1 process p4 -expect-cursor 4 0 process p4 -expect-cursor 0 1 -process p4 -screen-dump -stop +process p4 -screen-dump + +# Exercise CONS25 mode +process p4 -write "\x1b[=1T" +process p4 -write "\x1b[8z" +process p4 -write "\x1b[0x" +process p4 -write "\x1b[=1A" +process p4 -write "\x1b[=1;2B" +process p4 -write "\x1b[=1;2;3C" +process p4 -write "\x1b[=1F" +process p4 -write "\x1b[=1G" +process p4 -write "\x1b[=1S" +process p4 -writehex {0c 08 40 0d 0a 08} + +process p4 -expect-text 1 1 "@" +process p4 -expect-cursor 1 80 +process p4 -writehex "0c 41 0e 42 0f" +process p4 -expect-text 1 1 "A" +process p4 -expect-text 0 0 "B" +process p4 -write "\x1b[=0T" + +process p4 -writehex "0c 0a 0d 43 0a 08 08 0e 44 0f" + +process p4 -expect-text 3 1 "C" +process p4 -expect-text 4 1 "D" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:43 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:43 +0000 (UTC) Subject: [6.0] de72059f3 Plug a few more leaks Message-ID: <20180816085243.21D6198FFD@lists.varnish-cache.org> commit de72059f33c4fbc24f76d865842d2d90dad2f049 Author: Federico G. Schwindt Date: Sat Apr 14 08:56:29 2018 +0100 Plug a few more leaks diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 6776e88d7..8ad4a5a16 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -96,7 +96,7 @@ void cmd_server_gen_haproxy_conf(struct vsb *vsb); void vtc_loginit(char *buf, unsigned buflen); struct vtclog *vtc_logopen(const char *id); -void vtc_logclose(struct vtclog *vl); +void vtc_logclose(void *arg); void vtc_log(struct vtclog *vl, int lvl, const char *fmt, ...) v_printflike_(3, 4); void vtc_fatal(struct vtclog *vl, const char *, ...) diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c index c66b8a2cd..116efdd02 100644 --- a/bin/varnishtest/vtc_barrier.c +++ b/bin/varnishtest/vtc_barrier.c @@ -137,7 +137,7 @@ barrier_sock_thread(void *priv) AZ(pthread_mutex_lock(&b->mtx)); vl = vtc_logopen(b->name); - AN(vl); + pthread_cleanup_push(vtc_logclose, vl); sock = VTCP_listen_on("127.0.0.1:0", NULL, b->expected, &err); if (sock < 0) { @@ -219,7 +219,7 @@ barrier_sock_thread(void *priv) macro_undef(vl, b->name, "sock"); closefd(&sock); free(conns); - + pthread_cleanup_pop(1); return (NULL); } diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index 0a0cb6dbe..4b2f608fc 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -207,6 +207,7 @@ client_thread(void *priv) AN(*c->connect); vl = vtc_logopen(c->name); + pthread_cleanup_push(vtc_logclose, vl); vsb = macro_expand(vl, c->connect); AN(vsb); @@ -236,6 +237,7 @@ client_thread(void *priv) } vtc_log(vl, 2, "Ending"); VSB_destroy(&vsb); + pthread_cleanup_pop(1); return (NULL); } diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index db07d42c9..edfe79653 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -1865,6 +1865,21 @@ const struct cmds http_cmds[] = { { NULL, NULL } }; +static void +http_process_cleanup(void *arg) +{ + struct http *hp = arg; + + if (hp->h2) + stop_h2(hp); + VSB_destroy(&hp->vsb); + free(hp->rxbuf); + free(hp->rem_ip); + free(hp->rem_port); + free(hp->rem_path); + FREE_OBJ(hp); +} + int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, const char *addr) @@ -1906,16 +1921,10 @@ http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, strcpy(hp->rem_port, "0"); hp->rem_path = strdup(addr); } + pthread_cleanup_push(http_process_cleanup, hp); parse_string(spec, http_cmds, hp, vl); - if (hp->h2) - stop_h2(hp); retval = hp->fd; - VSB_destroy(&hp->vsb); - free(hp->rxbuf); - free(hp->rem_ip); - free(hp->rem_port); - free(hp->rem_path); - FREE_OBJ(hp); + pthread_cleanup_pop(1); return (retval); } diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c index 8f917d4f8..2c458f3d6 100644 --- a/bin/varnishtest/vtc_http2.c +++ b/bin/varnishtest/vtc_http2.c @@ -2541,6 +2541,7 @@ static void stream_delete(struct stream *s) { CHECK_OBJ_NOTNULL(s, STREAM_MAGIC); + free(s->body); free(s->spec); free(s->name); FREE_OBJ(s); diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 72108b1a6..d7ceefe89 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -90,8 +90,9 @@ vtc_logopen(const char *id) } void -vtc_logclose(struct vtclog *vl) +vtc_logclose(void *arg) { + struct vtclog *vl = arg; CHECK_OBJ_NOTNULL(vl, VTCLOG_MAGIC); if (pthread_getspecific(log_key) == vl) diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index 735b747fa..add0f1f46 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -194,6 +194,7 @@ logexp_delete(struct logexp *le) free(le->vname); free(le->query); VSM_Destroy(&le->vsm); + vtc_logclose(le->vl); FREE_OBJ(le); } diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 71ef165aa..8da7c56ef 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -240,8 +240,10 @@ tst_cb(const struct vev *ve, int what) jp->tst->filename, ecode ? "skipped" : "passed", t); } - if (jp->evt != NULL) + if (jp->evt != NULL) { VEV_Stop(vb, jp->evt); + free(jp->evt); + } FREE_OBJ(jp); return (1); diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 1307cd5fb..ca8c6a5d4 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -232,6 +232,7 @@ server_thread(void *priv) assert(s->sock >= 0); vl = vtc_logopen(s->name); + pthread_cleanup_push(vtc_logclose, vl); vtc_log(vl, 2, "Started on %s", s->listen); for (i = 0; i < s->repeat; i++) { @@ -255,6 +256,7 @@ server_thread(void *priv) VTCP_close(&fd); } vtc_log(vl, 2, "Ending"); + pthread_cleanup_pop(1); return (NULL); } @@ -288,6 +290,7 @@ server_dispatch_wrk(void *priv) assert(s->sock < 0); vl = vtc_logopen(s->name); + pthread_cleanup_push(vtc_logclose, vl); fd = s->fd; @@ -299,6 +302,7 @@ server_dispatch_wrk(void *priv) vtc_fatal(vl, "Shutdown failed: %s", strerror(errno)); VTCP_close(&s->fd); vtc_log(vl, 2, "Ending"); + pthread_cleanup_pop(1); return (NULL); } @@ -317,7 +321,8 @@ server_dispatch_thread(void *priv) assert(s->sock >= 0); vl = vtc_logopen(s->name); - AN(vl); + pthread_cleanup_push(vtc_logclose, vl); + vtc_log(vl, 2, "Dispatch started on %s", s->listen); while (1) { @@ -335,6 +340,7 @@ server_dispatch_thread(void *priv) s2->run = 1; AZ(pthread_create(&s2->tp, NULL, server_dispatch_wrk, s2)); } + pthread_cleanup_pop(1); NEEDLESS(return(NULL)); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:43 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:43 +0000 (UTC) Subject: [6.0] 87a7dfdf9 Polish Message-ID: <20180816085243.671669B021@lists.varnish-cache.org> commit 87a7dfdf9d20383ebb31c301d8d65aff6c4a937b Author: Federico G. Schwindt Date: Sat Apr 14 08:56:56 2018 +0100 Polish diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index 981c5bfea..7a427d5bf 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -462,8 +462,8 @@ mgt_reap_child(void) if (ev_poker != NULL) { VEV_Stop(mgt_evb, ev_poker); free(ev_poker); + ev_poker = NULL; } - ev_poker = NULL; /* Stop the listener */ if (ev_listen != NULL) { diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c index 2c458f3d6..b8857b3bb 100644 --- a/bin/varnishtest/vtc_http2.c +++ b/bin/varnishtest/vtc_http2.c @@ -293,8 +293,7 @@ clean_frame(struct frame **f) if ((*f)->type == TYPE_GOAWAY) free((*f)->md.goaway.debug); free((*f)->data); - free(*f); - *f = NULL; + FREE_OBJ(*f); } static void diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index b05d0ce28..44103f42b 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -396,16 +396,16 @@ process_delete(struct process *p) free(p->out); free(p->err); + for (i = 0; i < p->nlin; i++) + free(p->vram[i]); + free(p->vram); + /* * We do not delete the directory, it may contain useful stdout * and stderr files. They will be deleted on account of belonging * to the test's tmpdir. */ - for (i = 0; i < p->nlin; i++) - free(p->vram[i]); - free(p->vram); - /* XXX: MEMLEAK (?) */ FREE_OBJ(p); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:43 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:43 +0000 (UTC) Subject: [6.0] 9e7db2130 Try to appease Sun CC Message-ID: <20180816085243.8C6629B038@lists.varnish-cache.org> commit 9e7db2130f9ce14023d44d6ef341ec4d89ded050 Author: Federico G. Schwindt Date: Sat Apr 14 11:24:08 2018 +0100 Try to appease Sun CC diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index ca8c6a5d4..04199de11 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -340,7 +340,7 @@ server_dispatch_thread(void *priv) s2->run = 1; AZ(pthread_create(&s2->tp, NULL, server_dispatch_wrk, s2)); } - pthread_cleanup_pop(1); + NEEDLESS(pthread_cleanup_pop(1)); NEEDLESS(return(NULL)); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:43 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:43 +0000 (UTC) Subject: [6.0] 3f74c4c6f Just hide this whole thing from Sun CC for now Message-ID: <20180816085243.BD8789B046@lists.varnish-cache.org> commit 3f74c4c6faa13e7d26b7b04b21b32cb663472a3c Author: Federico G. Schwindt Date: Sat Apr 14 11:48:18 2018 +0100 Just hide this whole thing from Sun CC for now diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 04199de11..294305840 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -321,7 +321,9 @@ server_dispatch_thread(void *priv) assert(s->sock >= 0); vl = vtc_logopen(s->name); +#if !defined(__SUNPRO_C) pthread_cleanup_push(vtc_logclose, vl); +#endif vtc_log(vl, 2, "Dispatch started on %s", s->listen); @@ -340,7 +342,9 @@ server_dispatch_thread(void *priv) s2->run = 1; AZ(pthread_create(&s2->tp, NULL, server_dispatch_wrk, s2)); } - NEEDLESS(pthread_cleanup_pop(1)); +#if !defined(__SUNPRO_C) + pthread_cleanup_pop(1); +#endif NEEDLESS(return(NULL)); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:43 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:43 +0000 (UTC) Subject: [6.0] 41b791a33 Rework to avoid UB Message-ID: <20180816085244.034A49B062@lists.varnish-cache.org> commit 41b791a33ec5ad163e2f97f8689d91044d00abb2 Author: Federico G. Schwindt Date: Sat Apr 14 20:03:46 2018 +0100 Rework to avoid UB Fixes #2617 diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 8797c926e..6c3e2ce1f 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -669,8 +669,9 @@ http_GetHdrField(const struct http *hp, const char *hdr, ssize_t http_GetContentLength(const struct http *hp) { - ssize_t cl, cll; + ssize_t cl; const char *b; + unsigned n; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); @@ -680,11 +681,13 @@ http_GetContentLength(const struct http *hp) if (!vct_isdigit(*b)) return (-2); for (; vct_isdigit(*b); b++) { - cll = cl; + if (cl > (SSIZE_MAX / 10)) + return (-2); cl *= 10; - cl += *b - '0'; - if (cll != cl / 10) + n = *b - '0'; + if (cl > (SSIZE_MAX - n)) return (-2); + cl += n; } while (vct_islws(*b)) b++; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:44 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:44 +0000 (UTC) Subject: [6.0] d1875b20c Add test for #2617 Message-ID: <20180816085244.20EC39B076@lists.varnish-cache.org> commit d1875b20cbf8bcbb1f7cb370a0d15eda071a92d6 Author: Federico G. Schwindt Date: Sat Apr 14 20:19:24 2018 +0100 Add test for #2617 diff --git a/bin/varnishtest/tests/r02617.vtc b/bin/varnishtest/tests/r02617.vtc new file mode 100644 index 000000000..78d9d2a44 --- /dev/null +++ b/bin/varnishtest/tests/r02617.vtc @@ -0,0 +1,16 @@ +varnishtest "Test undefined-behaviour: signed integer overflow" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + +} -start + +client c1 { + txreq -hdr "Content-Length: 9223372036854775808" + rxresp + expect resp.status == 400 +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:44 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:44 +0000 (UTC) Subject: [6.0] 4b70c6249 More Teken coverage Message-ID: <20180816085244.4BA059B08B@lists.varnish-cache.org> commit 4b70c62498a5e154c8f656510d6a593915999a5c Author: Poul-Henning Kamp Date: Mon Apr 16 05:26:48 2018 +0000 More Teken coverage diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index a79ceed8b..868fa5404 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -57,7 +57,13 @@ process p4 -write "4\x08>\x1b[A\x1b[Cv\x1b[22A^\x1b[79D^\x1b[;2H<\n\n\n\n" process p4 -write "\n\n\n\n\n\n\n\n\x1b[B\x1b[11B\x08<\x1b[24;Hv\x1b[12;1H" process p4 -write "111111112222222333333\x0d\x0a111111112" process p4 -write "222222333333\x0d\x0a111111112222222333333 UTF8: " -process p4 -writehex {c2 a2 20 e2 82 ac 20 f0 9f 90 b0} +process p4 -writehex {c2 a2 20} +process p4 -writehex {e2 82 ac 20} +process p4 -writehex {f0 90 80 80 20} +process p4 -writehex {f0 9f 90 b0 20} +process p4 -writehex {f0 a0 80 80 20} +process p4 -writehex {f0 b0 80 80 20} +process p4 -write "\x1b[22;24;25;27;30;47m" process p4 -write "\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" process p4 -write ";12H\x1b[K\x1b[13;12H\x1b[0K\x1b[14;12H\x1b[1K\x1b" process p4 -write "[15;12H\x1b[2K\x1b[3;1Hline3 <\x0d\x0a" @@ -68,13 +74,15 @@ process p4 -expect-cursor 4 0 process p4 -expect-cursor 0 1 process p4 -screen-dump -# Exercise CONS25 mode +# Also exercise CONS25 mode process p4 -write "\x1b[=1T" +process p4 -write "\x1b[=2T" process p4 -write "\x1b[8z" process p4 -write "\x1b[0x" process p4 -write "\x1b[=1A" process p4 -write "\x1b[=1;2B" process p4 -write "\x1b[=1;2;3C" +process p4 -write "\x1b[=1;2;3;4C" process p4 -write "\x1b[=1F" process p4 -write "\x1b[=1G" process p4 -write "\x1b[=1S" @@ -91,3 +99,8 @@ process p4 -writehex "0c 0a 0d 43 0a 08 08 0e 44 0f" process p4 -expect-text 3 1 "C" process p4 -expect-text 4 1 "D" +process p4 -write "\x1b[2T" +process p4 -expect-text 5 1 "C" +process p4 -expect-text 6 1 "D" +process p4 -write "\x1b[3S" +process p4 -expect-text 3 1 "D" diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 44103f42b..c182ed3e2 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -346,6 +346,30 @@ term_expect_cursor(struct process *pp, const char *lin, const char *col) VSB_destroy(&vsb); \ } while (0) +static void +process_coverage(struct process *p) +{ + const teken_attr_t *a; + teken_pos_t pos; + int fg, bg; + + // Code-Coverage of Teken + + (void)teken_get_sequence(p->tek, TKEY_UP); + (void)teken_get_sequence(p->tek, TKEY_F1); + (void)teken_256to8(0); + (void)teken_256to16(0); + a = teken_get_defattr(p->tek); + teken_set_defattr(p->tek, a); + a = teken_get_curattr(p->tek); + teken_set_curattr(p->tek, a); + (void)teken_get_winsize(p->tek); + pos.tp_row = 0; + pos.tp_col = 8; + teken_set_cursor(p->tek, &pos); + teken_get_defattr_cons25(p->tek, &fg, &bg); +} + static struct process * process_new(const char *name) { @@ -374,6 +398,7 @@ process_new(const char *name) VTAILQ_INSERT_TAIL(&processes, p, list); teken_init(p->tek, &process_teken_func, p); term_resize(p, 24, 80); + process_coverage(p); return (p); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:44 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:44 +0000 (UTC) Subject: [6.0] 50b8dd2a5 Tighten up checks Message-ID: <20180816085244.6F9659B09B@lists.varnish-cache.org> commit 50b8dd2a580cd7f6efbe2564ef5c1a1ebb9d0cd9 Author: Federico G. Schwindt Date: Mon Apr 16 22:15:37 2018 +0100 Tighten up checks diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c index 9772ac800..4bef5e711 100644 --- a/lib/libvarnish/vtim.c +++ b/lib/libvarnish/vtim.c @@ -243,6 +243,9 @@ VTIM_parse(const char *p) int hour = 0, min = 0, sec = 0; int d, leap; + if (p == NULL || *p == '\0') + FAIL(); + while (*p == ' ') p++; diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c index bb2be44b8..ba10fa513 100644 --- a/lib/libvmod_std/vmod_std_conversions.c +++ b/lib/libvmod_std/vmod_std_conversions.c @@ -194,8 +194,6 @@ vmod_time(VRT_CTX, VCL_STRING p, VCL_TIME d) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - if (p == NULL) - return (d); r = VTIM_parse(p); if (r) return (r); diff --git a/lib/libvmod_std/vmod_std_fileread.c b/lib/libvmod_std/vmod_std_fileread.c index 201d743f7..1bb003e48 100644 --- a/lib/libvmod_std/vmod_std_fileread.c +++ b/lib/libvmod_std/vmod_std_fileread.c @@ -90,6 +90,9 @@ vmod_fileread(VRT_CTX, struct vmod_priv *priv, CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(priv); + if (file_name == NULL) + return (NULL); + if (priv->priv != NULL) { CAST_OBJ_NOTNULL(frf, priv->priv, CACHED_FILE_MAGIC); if (!strcmp(file_name, frf->file_name)) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:44 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:44 +0000 (UTC) Subject: [6.0] 386eae1e3 More coverage Message-ID: <20180816085244.94C2C9B0AE@lists.varnish-cache.org> commit 386eae1e3b0cbd086a90c6c6f4924e6cc84ab2dd Author: Federico G. Schwindt Date: Mon Apr 16 22:17:25 2018 +0100 More coverage diff --git a/bin/varnishtest/tests/m00014.vtc b/bin/varnishtest/tests/m00014.vtc index 6d60def93..f3272a6b3 100644 --- a/bin/varnishtest/tests/m00014.vtc +++ b/bin/varnishtest/tests/m00014.vtc @@ -9,40 +9,50 @@ varnish v1 -vcl+backend { import std; sub vcl_deliver { - set resp.http.url = std.querysort(req.url); + set resp.http.url = std.querysort(req.http.url); } } -start client c1 { - txreq -url "/foo/bar?t=0&b=0&p=0&c=5" + txreq -hdr "url: /foo/bar?t=0&b=0&p=0&c=5" rxresp expect resp.http.url == "/foo/bar?b=0&c=5&p=0&t=0" delay .1 - txreq -url "/foo/bar?coa=0&co=0" + txreq -hdr "url: /foo/bar?coa=0&co=0" rxresp expect resp.http.url == "/foo/bar?co=0&coa=0" delay .1 - txreq -url "/foo/bar?a=0&&&&&" + txreq -hdr "url: /foo/bar?a=0&&&&&" rxresp expect resp.http.url == "/foo/bar?a=0" - txreq -url "/foo/bar?&a=0&&&&&z&w&x&" + txreq -hdr "url: /foo/bar?&a=0&&&&&z&w&x&" rxresp expect resp.http.url == "/foo/bar?a=0&w&x&z" delay .1 - txreq -url "/foo/bar?&" + txreq -hdr "url: /foo/bar?&" rxresp expect resp.http.url == "/foo/bar?" delay .1 - txreq -url "/foo/bar" + txreq -hdr "url: /foo/bar?t=0" + rxresp + expect resp.http.url == "/foo/bar?t=0" + + delay .1 + + txreq -hdr "url: /foo/bar" rxresp expect resp.http.url == "/foo/bar" + + txreq + rxresp + expect resp.http.url == "" } -run diff --git a/bin/varnishtest/tests/m00018.vtc b/bin/varnishtest/tests/m00018.vtc index 33d68f34a..f41faf2af 100644 --- a/bin/varnishtest/tests/m00018.vtc +++ b/bin/varnishtest/tests/m00018.vtc @@ -1,6 +1,6 @@ varnishtest "Test std.substr" -server s1 -repeat 2 { +server s1 { rxreq txresp } -start @@ -9,16 +9,16 @@ varnish v1 -vcl+backend { import std; sub vcl_deliver { - set resp.http.sub = std.strstr(req.url, "b"); + set resp.http.sub1 = std.strstr(req.http.one, "b"); + set resp.http.sub2 = std.strstr(req.http.two, "b"); + set resp.http.sub3 = std.strstr(req.http.unset, "b"); } } -start client c1 { - txreq -url "/foobar" + txreq -hdr "one: foobar" -hdr "two: quux" rxresp - expect resp.http.sub == "bar" - - txreq -url "/quux" - rxresp - expect resp.http.sub == "" + expect resp.http.sub1 == "bar" + expect resp.http.sub2 == "" + expect resp.http.sub3 == "" } -run diff --git a/bin/varnishtest/tests/m00020.vtc b/bin/varnishtest/tests/m00020.vtc index 8fe5c83d1..eb2eb0f5b 100644 --- a/bin/varnishtest/tests/m00020.vtc +++ b/bin/varnishtest/tests/m00020.vtc @@ -127,4 +127,7 @@ client c1 { expect resp.http.x-date != "Wed, 29 Feb 2012 00:00:00 GMT" delay .1 + txreq + rxresp + expect resp.http.x-date != } -run diff --git a/bin/varnishtest/tests/m00026.vtc b/bin/varnishtest/tests/m00026.vtc index 8c5f71783..3659eb367 100644 --- a/bin/varnishtest/tests/m00026.vtc +++ b/bin/varnishtest/tests/m00026.vtc @@ -11,6 +11,7 @@ varnish v1 -vcl { sub vcl_synth { set resp.http.X-PATH = std.getenv("PATH"); + set resp.http.X-unset = std.getenv(req.http.unset); } } -start @@ -18,4 +19,5 @@ client c1 { txreq rxresp expect resp.http.X-PATH ~ "^/" + expect resp.http.X-unset == "" } -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:44 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:44 +0000 (UTC) Subject: [6.0] 95d2dd725 Yet more Teken coverage Message-ID: <20180816085244.B90B19B0B8@lists.varnish-cache.org> commit 95d2dd72563769cffab6af631d81c4ee5c20ff09 Author: Poul-Henning Kamp Date: Tue Apr 17 06:57:07 2018 +0000 Yet more Teken coverage diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index 868fa5404..e2601f337 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -63,7 +63,7 @@ process p4 -writehex {f0 90 80 80 20} process p4 -writehex {f0 9f 90 b0 20} process p4 -writehex {f0 a0 80 80 20} process p4 -writehex {f0 b0 80 80 20} -process p4 -write "\x1b[22;24;25;27;30;47m" +process p4 -write "\x1b[22;24;25;27;30;47;49;97;107m" process p4 -write "\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" process p4 -write ";12H\x1b[K\x1b[13;12H\x1b[0K\x1b[14;12H\x1b[1K\x1b" process p4 -write "[15;12H\x1b[2K\x1b[3;1Hline3 <\x0d\x0a" @@ -104,3 +104,17 @@ process p4 -expect-text 5 1 "C" process p4 -expect-text 6 1 "D" process p4 -write "\x1b[3S" process p4 -expect-text 3 1 "D" + +process p4 -write "\x1b[4;200H%" +process p4 -expect-text 4 80 "%" + +process p4 -write "\x1b[7;7H\x09X\x09Y\x09Z\x1b[2ZW\x1b[2Ew\x1b[F*" + +process p4 -expect-text 7 17 "W" +process p4 -expect-text 9 1 "w" +process p4 -expect-text 8 1 "*" + +process p4 -write "\x1b[10;4HABCDEFGHIJKLMN" +process p4 -write "\x1b[8G\x1b[2X>" +process p4 -expect-text 10 8 ">" +process p4 -screen-dump From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:44 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:44 +0000 (UTC) Subject: [6.0] 34be7660c Max 8 numerical arguments, but test overflow while at it. Message-ID: <20180816085244.E087F9B0D1@lists.varnish-cache.org> commit 34be7660c181e0ac12a06aa0f56756bd4c9694f1 Author: Poul-Henning Kamp Date: Tue Apr 17 09:00:26 2018 +0000 Max 8 numerical arguments, but test overflow while at it. diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index e2601f337..42e458aa4 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -64,6 +64,8 @@ process p4 -writehex {f0 9f 90 b0 20} process p4 -writehex {f0 a0 80 80 20} process p4 -writehex {f0 b0 80 80 20} process p4 -write "\x1b[22;24;25;27;30;47;49;97;107m" +process p4 -write "\x1b[22;24;25;27;30m" +process p4 -write "\x1b[47;49;97;107m" process p4 -write "\x0d\x0a111111112222222333333\x0d\x0a\x1b[12" process p4 -write ";12H\x1b[K\x1b[13;12H\x1b[0K\x1b[14;12H\x1b[1K\x1b" process p4 -write "[15;12H\x1b[2K\x1b[3;1Hline3 <\x0d\x0a" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] 112fc77da Test for MAX_FRAME_SIZE in h2_frame_complete Message-ID: <20180816085245.112249B0E9@lists.varnish-cache.org> commit 112fc77dae73128238f3577d74a99b896f21c65c Author: Dag Haavi Finstad Date: Tue Apr 17 13:53:26 2018 +0200 Test for MAX_FRAME_SIZE in h2_frame_complete Return HTC_S_OVERFLOW if exceeded. This is a quick-fix for #2624, where we close the connection if a client exceeds MAX_FRAME_SIZE. More proper handling with draining the rest of the frame for the specific frames types that allow it (rfc7540 section 4.2) to come later. Fixes: #2624 diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 39d97e64c..6a0c92be5 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -814,14 +814,18 @@ h2_req_fail(struct req *req, enum sess_close reason) static enum htc_status_e v_matchproto_(htc_complete_f) h2_frame_complete(struct http_conn *htc) { + struct h2_sess *h2; int l; unsigned u; CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + CAST_OBJ_NOTNULL(h2, htc->priv, H2_SESS_MAGIC); l = htc->rxbuf_e - htc->rxbuf_b; if (l < 9) return (HTC_S_MORE); u = vbe32dec(htc->rxbuf_b) >> 8; + if (l > h2->local_settings.max_frame_size + 9) + return (HTC_S_OVERFLOW); if (l < u + 9) // XXX: Only for !DATA frames return (HTC_S_MORE); return (HTC_S_COMPLETE); @@ -1032,6 +1036,7 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2) /* FALLTHROUGH */ default: + /* XXX: HTC_S_OVERFLOW / FRAME_SIZE_ERROR handling */ Lck_Lock(&h2->sess->mtx); VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs); h2->error = H2CE_NO_ERROR; diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index e34f8240a..b2ab70f96 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -349,6 +349,8 @@ h2_new_session(struct worker *wrk, void *arg) h2 = h2_init_sess(wrk, sp, &h2s, req->err_code == H2_PU_MARKER ? req : NULL); h2->req0 = h2_new_req(wrk, h2, 0, NULL); + AZ(h2->htc->priv); + h2->htc->priv = h2; if (req->err_code == H2_OU_MARKER && !h2_ou_session(wrk, h2, req)) { assert(h2->refcnt == 1); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] 2f7cbaa64 Test Teken responses Message-ID: <20180816085245.378D29B109@lists.varnish-cache.org> commit 2f7cbaa648e1c9b2701db2e3cb6395d0d53ee39e Author: Poul-Henning Kamp Date: Tue Apr 17 12:38:44 2018 +0000 Test Teken responses diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index 42e458aa4..12f9bda36 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -116,7 +116,30 @@ process p4 -expect-text 7 17 "W" process p4 -expect-text 9 1 "w" process p4 -expect-text 8 1 "*" -process p4 -write "\x1b[10;4HABCDEFGHIJKLMN" +process p4 -write "\x1b[10;4HABCDEFGHIJKLMN\x1b(A#$%\x1b)A" process p4 -write "\x1b[8G\x1b[2X>" process p4 -expect-text 10 8 ">" process p4 -screen-dump + +# Safely test responses +process p5 -hexdump "stty raw -echo; echo '*' ; tr '\x02\x1b' '\x1b@'" -start +process p5 -expect-text 0 0 "*" +process p5 -write "\x02[3;1HA\x02[5n" +process p5 -expect-text 3 0 "n" +process p5 -write "\x02[4;1HB\x02[6n" +process p5 -expect-text 4 0 "R" +process p5 -write "\x02[5;1HC\x02[15n" +process p5 -expect-text 5 0 "n" +process p5 -write "\x02[6;1HD\x02[25n" +process p5 -expect-text 6 0 "n" +process p5 -write "\x02[7;1HE\x02[26n" +process p5 -expect-text 7 0 "n" +process p5 -write "\x02[8;1HF\x02[?26n" +process p5 -expect-text 8 0 "n" +process p5 -write "\x02[9;1HG\x02Pfutfutfut\x01" +process p5 -write "\x02[10;1HH\x02]futfutfut\x01" +process p5 -write "\x02[11;1HI\x02[>c" +process p5 -expect-text 11 0 "c" +process p5 -write "\x02[24;1HW" +process p5 -expect-text 0 0 "W" +process p5 -screen-dump From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] ad9aab0bf Trust it to linux to break even tr(1). Message-ID: <20180816085245.622949B12A@lists.varnish-cache.org> commit ad9aab0bf49d8b3ca76d2c1f4a469e084a405264 Author: Poul-Henning Kamp Date: Tue Apr 17 16:46:10 2018 +0000 Trust it to linux to break even tr(1). Supress terminal responses by default and hope they look right. diff --git a/bin/varnishtest/tests/a00000.vtc b/bin/varnishtest/tests/a00000.vtc index 12f9bda36..9bd14bc67 100644 --- a/bin/varnishtest/tests/a00000.vtc +++ b/bin/varnishtest/tests/a00000.vtc @@ -121,25 +121,16 @@ process p4 -write "\x1b[8G\x1b[2X>" process p4 -expect-text 10 8 ">" process p4 -screen-dump -# Safely test responses -process p5 -hexdump "stty raw -echo; echo '*' ; tr '\x02\x1b' '\x1b@'" -start -process p5 -expect-text 0 0 "*" -process p5 -write "\x02[3;1HA\x02[5n" -process p5 -expect-text 3 0 "n" -process p5 -write "\x02[4;1HB\x02[6n" -process p5 -expect-text 4 0 "R" -process p5 -write "\x02[5;1HC\x02[15n" -process p5 -expect-text 5 0 "n" -process p5 -write "\x02[6;1HD\x02[25n" -process p5 -expect-text 6 0 "n" -process p5 -write "\x02[7;1HE\x02[26n" -process p5 -expect-text 7 0 "n" -process p5 -write "\x02[8;1HF\x02[?26n" -process p5 -expect-text 8 0 "n" -process p5 -write "\x02[9;1HG\x02Pfutfutfut\x01" -process p5 -write "\x02[10;1HH\x02]futfutfut\x01" -process p5 -write "\x02[11;1HI\x02[>c" -process p5 -expect-text 11 0 "c" -process p5 -write "\x02[24;1HW" -process p5 -expect-text 0 0 "W" -process p5 -screen-dump +# Test responses +process p4 -write "\x1b[3;1HA\x1b[5n" +process p4 -write "\x1b[4;1HB\x1b[6n" +process p4 -write "\x1b[5;1HC\x1b[15n" +process p4 -write "\x1b[6;1HD\x1b[25n" +process p4 -write "\x1b[7;1HE\x1b[26n" +process p4 -write "\x1b[8;1HF\x1b[?26n" +process p4 -write "\x1b[9;1HG\x1bPfutfutfut\x01" +process p4 -write "\x1b[10;1HH\x1b]futfutfut\x01" +process p4 -write "\x1b[11;1HI\x1b[>c" +process p4 -write "\x1b[24;1HW" +process p4 -expect-text 24 1 "W" +process p4 -screen-dump diff --git a/bin/varnishtest/tests/a00001.vtc b/bin/varnishtest/tests/a00001.vtc index dfca677e0..b6628d807 100644 --- a/bin/varnishtest/tests/a00001.vtc +++ b/bin/varnishtest/tests/a00001.vtc @@ -2,7 +2,7 @@ varnishtest "Test Teken terminal emulator" feature cmd "vttest --version 2>&1 | grep -q Usage" -process p4 {vttest} -start +process p4 {vttest} -ansi-response -start process p4 -expect-text 21 11 "Enter choice number (0 - 12):" process p4 -screen_dump diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index c182ed3e2..7ab093b90 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -88,6 +88,7 @@ struct process { int nlin; int ncol; + int ansi_response; char **vram; teken_t tek[1]; }; @@ -174,10 +175,12 @@ term_respond(void *priv, const void *p, size_t l) CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC); vtc_dump(pp->vl, 4, "term_response", p, l); - r = write(pp->fd_term, p, l); - if (r != l) - vtc_fatal(pp->vl, "Could not write to process: %s", - strerror(errno)); + if (pp->ansi_response) { + r = write(pp->fd_term, p, l); + if (r != l) + vtc_fatal(pp->vl, "Could not write to process: %s", + strerror(errno)); + } } static void @@ -1010,6 +1013,10 @@ cmd_process(CMD_ARGS) process_wait(p); continue; } + if (!strcmp(*av, "-ansi-response")) { + p->ansi_response = 1; + continue; + } if (!strcmp(*av, "-expect-text")) { AN(av[1]); AN(av[2]); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] 322bcca64 Make the individual VFP->init()'s responsible for the objflags. Message-ID: <20180816085245.869739B149@lists.varnish-cache.org> commit 322bcca6431ce0920e0330dd72b3a5af2fa6eebb Author: Poul-Henning Kamp Date: Tue Apr 17 21:00:17 2018 +0000 Make the individual VFP->init()'s responsible for the objflags. diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 906c2ba3a..5411df238 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -156,6 +156,7 @@ vfp_esi_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe) ALLOC_OBJ(vef, VEF_MAGIC); if (vef == NULL) return (VFP_ERROR); + vc->obj_flags |= OF_GZIPED | OF_CHGGZIP | OF_ESIPROC; vef->vgz = VGZ_NewGzip(vc->wrk->vsl, "G F E"); vef->vep = VEP_Init(vc, vc->req, vfp_vep_callback, vef); vef->ibuf_sz = cache_param->gzip_buffer; @@ -229,6 +230,7 @@ vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe) ALLOC_OBJ(vef, VEF_MAGIC); if (vef == NULL) return (VFP_ERROR); + vc->obj_flags |= OF_ESIPROC; vef->vep = VEP_Init(vc, vc->req, NULL, NULL); vfe->priv1 = vef; return (VFP_OK); diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 27e7e70c9..aacbc69e6 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -503,6 +503,7 @@ vbf_stp_fetchbody(struct worker *wrk, struct busyobj *bo) static int vbf_figure_out_vfp(struct busyobj *bo) { + int is_gzip, is_gunzip; /* * The VCL variables beresp.do_g[un]zip tells us how we want the @@ -543,26 +544,26 @@ vbf_figure_out_vfp(struct busyobj *bo) if (!cache_param->http_gzip_support) bo->do_gzip = bo->do_gunzip = 0; - bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"); - bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL); - assert(bo->is_gzip == 0 || bo->is_gunzip == 0); + is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"); + is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL); + assert(is_gzip == 0 || is_gunzip == 0); /* We won't gunzip unless it is gzip'ed */ - if (bo->do_gunzip && !bo->is_gzip) + if (bo->do_gunzip && !is_gzip) bo->do_gunzip = 0; /* We wont gzip unless if it already is gzip'ed */ - if (bo->do_gzip && !bo->is_gunzip) + if (bo->do_gzip && !is_gunzip) bo->do_gzip = 0; /* But we can't do both at the same time */ assert(bo->do_gzip == 0 || bo->do_gunzip == 0); - if (bo->do_gunzip || (bo->is_gzip && bo->do_esi)) + if (bo->do_gunzip || (is_gzip && bo->do_esi)) if (VFP_Push(bo->vfc, &VFP_gunzip) == NULL) return (-1); - if (bo->do_esi && (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip))) + if (bo->do_esi && (bo->do_gzip || (is_gzip && !bo->do_gunzip))) return (VFP_Push(bo->vfc, &VFP_esi_gzip) == NULL ? -1 : 0); if (bo->do_esi) @@ -571,7 +572,7 @@ vbf_figure_out_vfp(struct busyobj *bo) if (bo->do_gzip) return (VFP_Push(bo->vfc, &VFP_gzip) == NULL ? -1 : 0); - if (bo->is_gzip && !bo->do_gunzip) + if (is_gzip && !bo->do_gunzip) return (VFP_Push(bo->vfc, &VFP_testgunzip) == NULL ? -1 : 0); return (0); @@ -614,14 +615,10 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) return (F_STP_ERROR); } - if (bo->do_esi) - ObjSetFlag(bo->wrk, bo->fetch_objcore, OF_ESIPROC, 1); - - if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip)) - ObjSetFlag(bo->wrk, bo->fetch_objcore, OF_GZIPED, 1); - - if (bo->do_gzip || bo->do_gunzip) - ObjSetFlag(bo->wrk, bo->fetch_objcore, OF_CHGGZIP, 1); +#define OBJ_FLAG(U, l, v) \ + if (bo->vfc->obj_flags & OF_##U) \ + ObjSetFlag(bo->wrk, bo->fetch_objcore, OF_##U, 1); +#include "tbl/obj_attr.h" if (!(bo->fetch_objcore->flags & OC_F_PASS) && http_IsStatus(bo->beresp, 200) && ( diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index 474583613..f6dae16e9 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -82,6 +82,7 @@ struct vfp_ctx { struct vfp_entry_s vfp; struct vfp_entry *vfp_nxt; + unsigned obj_flags; }; enum vfp_status VFP_Suck(struct vfp_ctx *, void *p, ssize_t *lp); diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 72a86dd99..2c6e9cea7 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -446,13 +446,18 @@ vfp_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe) if (http_GetHdr(vc->resp, H_Content_Encoding, NULL)) return (VFP_NULL); vg = VGZ_NewGzip(vc->wrk->vsl, vfe->vfp->priv1); + vc->obj_flags |= OF_GZIPED | OF_CHGGZIP; } else { if (!http_HdrIs(vc->resp, H_Content_Encoding, "gzip")) return (VFP_NULL); - if (vfe->vfp == &VFP_gunzip) + if (vfe->vfp == &VFP_gunzip) { vg = VGZ_NewGunzip(vc->wrk->vsl, vfe->vfp->priv1); - else + vc->obj_flags &= ~OF_GZIPED; + vc->obj_flags |= OF_CHGGZIP; + } else { vg = VGZ_NewTestGunzip(vc->wrk->vsl, vfe->vfp->priv1); + vc->obj_flags |= OF_GZIPED; + } } if (vg == NULL) return (VFP_ERROR); diff --git a/include/tbl/bo_flags.h b/include/tbl/bo_flags.h index 575769997..88b8eebe3 100644 --- a/include/tbl/bo_flags.h +++ b/include/tbl/bo_flags.h @@ -36,8 +36,6 @@ BO_FLAG(do_gunzip, 1, 1, "") BO_FLAG(do_stream, 1, 1, "") BO_FLAG(do_pass, 0, 0, "") BO_FLAG(uncacheable, 0, 0, "") -BO_FLAG(is_gzip, 0, 0, "") -BO_FLAG(is_gunzip, 0, 0, "") BO_FLAG(was_304, 1, 0, "") BO_FLAG(is_bgfetch, 0, 0, "") #undef BO_FLAG From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] ed4639cd7 Let VPF's handle their own 206 policy. Message-ID: <20180816085245.AAEB39B161@lists.varnish-cache.org> commit ed4639cd752698aa50241354f18293a0227bafeb Author: Poul-Henning Kamp Date: Tue Apr 17 21:26:34 2018 +0000 Let VPF's handle their own 206 policy. diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index 5411df238..acc110481 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -153,6 +153,11 @@ vfp_esi_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe) CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vc->req, HTTP_MAGIC); CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); + if (http_GetStatus(vc->resp) == 206) { + VSLb(vc->wrk->vsl, SLT_VCL_Error, + "Attempted ESI on partial (206) response"); + return (VFP_ERROR); + } ALLOC_OBJ(vef, VEF_MAGIC); if (vef == NULL) return (VFP_ERROR); @@ -227,6 +232,11 @@ vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe) CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vc->req, HTTP_MAGIC); + if (http_GetStatus(vc->resp) == 206) { + VSLb(vc->wrk->vsl, SLT_VCL_Error, + "Attempted ESI on partial (206) response"); + return (VFP_ERROR); + } ALLOC_OBJ(vef, VEF_MAGIC); if (vef == NULL) return (VFP_ERROR); diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index aacbc69e6..ee6091dab 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -516,22 +516,8 @@ vbf_figure_out_vfp(struct busyobj *bo) * no Content-Encoding --> object is not gzip'ed. * anything else --> do nothing wrt gzip * - * On partial responses (206 on pass), we fail if do_esi is - * requested because it could leak partial esi-directives, and - * ignore gzipery, because it makes no sense. - * */ - if (http_GetStatus(bo->beresp) == 206) { - if (bo->do_esi) { - VSLb(bo->vsl, SLT_VCL_Error, - "beresp.do_esi on partial response"); - return (-1); - } - bo->do_gzip = bo->do_gunzip = 0; - return (0); - } - /* No body -> done */ if (bo->htc->body_status == BS_NONE || bo->htc->content_length == 0) { diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 2c6e9cea7..3694c0ad2 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -442,6 +442,13 @@ vfp_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe) CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); + /* + * G(un)zip makes no sence on partial responses, but since + * it is an pure 1:1 transform, we can just ignore it. + */ + if (http_GetStatus(vc->resp) == 206) + return (VFP_NULL); + if (vfe->vfp == &VFP_gzip) { if (http_GetHdr(vc->resp, H_Content_Encoding, NULL)) return (VFP_NULL); diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index fe8cdb34d..c77cca91b 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -102,7 +102,7 @@ THR_SetName(const char *name) AZ(pthread_setspecific(name_key, name)); #if defined(HAVE_PTHREAD_SET_NAME_NP) - (void)pthread_set_name_np(pthread_self(), name); + pthread_set_name_np(pthread_self(), name); #elif defined(HAVE_PTHREAD_SETNAME_NP) #if defined(__APPLE__) (void)pthread_setname_np(name); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] b85ded2f7 Constify Message-ID: <20180816085245.C979C9B179@lists.varnish-cache.org> commit b85ded2f7c6bff43bbaeb4457630f268fcbb26dc Author: Poul-Henning Kamp Date: Tue Apr 17 22:28:32 2018 +0000 Constify Conflicts: bin/varnishd/cache/cache.h Arguably, this is a breaking change in $ABI vrt. diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 582f70bf4..f349d4f54 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -750,7 +750,7 @@ unsigned WS_Reserve(struct ws *ws, unsigned bytes); unsigned WS_ReserveLumps(struct ws *ws, size_t sz); void WS_MarkOverflow(struct ws *ws); void WS_Release(struct ws *ws, unsigned bytes); -void WS_ReleaseP(struct ws *ws, char *ptr); +void WS_ReleaseP(struct ws *ws, const char *ptr); void WS_Assert(const struct ws *ws); void WS_Reset(struct ws *ws, uintptr_t); void *WS_Alloc(struct ws *ws, unsigned bytes); diff --git a/bin/varnishd/cache/cache_ws.c b/bin/varnishd/cache/cache_ws.c index a58f6573a..3ec5ec017 100644 --- a/bin/varnishd/cache/cache_ws.c +++ b/bin/varnishd/cache/cache_ws.c @@ -275,7 +275,7 @@ WS_Release(struct ws *ws, unsigned bytes) } void -WS_ReleaseP(struct ws *ws, char *ptr) +WS_ReleaseP(struct ws *ws, const char *ptr) { WS_Assert(ws); DSL(DBG_WORKSPACE, 0, "WS_ReleaseP(%p, %p (%zd))", ws, ptr, ptr - ws->f); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:45 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:45 +0000 (UTC) Subject: [6.0] 5cde1b151 fix status code typo Message-ID: <20180816085245.E88BF9B192@lists.varnish-cache.org> commit 5cde1b15103196f673272e4c3e9a9c4dfa509755 Author: Nils Goroll Date: Tue Apr 17 08:14:29 2018 +0200 fix status code typo Thank you to @martin-uplex for the review diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst index d8c9861bd..690f337ef 100644 --- a/doc/sphinx/users-guide/vcl-built-in-subs.rst +++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst @@ -440,7 +440,7 @@ based on the response status and the response headers ``Age``, * If present and valid, the value of the ``Age`` header is effectively deduced from all ttl calculations. -* For status codes 200, 203, 204, 300, 401, 304, 404, 410 and 414: +* For status codes 200, 203, 204, 300, 301, 304, 404, 410 and 414: * If ``Cache-Control`` contains an ``s-maxage`` or ``max-age`` field (in that order of preference), the ttl is set to the respective From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:46 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:46 +0000 (UTC) Subject: [6.0] f02325029 promote resp.body / beresp.body syntax a bit more Message-ID: <20180816085246.2374D9B1BB@lists.varnish-cache.org> commit f02325029a5a9e3b2c093e9018aae5e0b52606fd Author: Nils Goroll Date: Wed Apr 18 11:54:31 2018 +0200 promote resp.body / beresp.body syntax a bit more Should we plan to phase out synthetic() ? diff --git a/bin/varnishtest/tests/b00017.vtc b/bin/varnishtest/tests/b00017.vtc index 42c96feaa..29fbe9e69 100644 --- a/bin/varnishtest/tests/b00017.vtc +++ b/bin/varnishtest/tests/b00017.vtc @@ -9,7 +9,7 @@ varnish v1 -vcl { } sub vcl_synth { - synthetic("Custom vcl_synth's synth output"); + set resp.body = "Custom vcl_synth's body"; return (deliver); } } -start @@ -18,8 +18,9 @@ client c1 { txreq -url "/" rxresp expect resp.status == 888 - expect resp.bodylen == 31 expect resp.http.connection != close + expect resp.bodylen == 23 + expect resp.body == "Custom vcl_synth's body" } -run varnish v1 -expect s_synth == 1 diff --git a/bin/varnishtest/tests/c00063.vtc b/bin/varnishtest/tests/c00063.vtc index b5c2cfe17..5b0a61e64 100644 --- a/bin/varnishtest/tests/c00063.vtc +++ b/bin/varnishtest/tests/c00063.vtc @@ -8,7 +8,7 @@ varnish v1 -vcl { set beresp.ttl = 1s; set beresp.grace = 3s; set beresp.http.foobar = "BLA" + bereq.xid; - synthetic(beresp.http.foobar); + set beresp.body = beresp.http.foobar; return (deliver); } } -start @@ -24,9 +24,11 @@ client c1 { txreq rxresp expect resp.http.foobar == "BLA1002" + expect resp.body == "BLA1002" delay 3 txreq rxresp expect resp.http.foobar == "BLA1004" + expect resp.body == "BLA1004" } -run diff --git a/bin/varnishtest/tests/c00068.vtc b/bin/varnishtest/tests/c00068.vtc index 313ca9ba4..88a47b631 100644 --- a/bin/varnishtest/tests/c00068.vtc +++ b/bin/varnishtest/tests/c00068.vtc @@ -37,7 +37,7 @@ varnish v1 -vcl+backend { return (restart); } else { set resp.http.restarts = req.restarts; - synthetic(req.restarts); + set resp.body = req.restarts; } } return (deliver); diff --git a/bin/varnishtest/tests/m00004.vtc b/bin/varnishtest/tests/m00004.vtc index f554a01f5..c418b8fb4 100644 --- a/bin/varnishtest/tests/m00004.vtc +++ b/bin/varnishtest/tests/m00004.vtc @@ -42,8 +42,8 @@ varnish v1 -vcl+backend { } sub vcl_synth { - synthetic("Response was served by " - + std.fileread("${tmpdir}/m00004_file_four")); + set resp.body = "Response was served by " + + std.fileread("${tmpdir}/m00004_file_four"); return(deliver); } } -start @@ -111,8 +111,8 @@ varnish v1 -vcl+backend { } sub vcl_synth { - synthetic("Response was served by " - + std.fileread("${tmpdir}/m00004_file_four")); + set resp.body = "Response was served by " + + std.fileread("${tmpdir}/m00004_file_four"); return(deliver); } } diff --git a/bin/varnishtest/tests/r01688.vtc b/bin/varnishtest/tests/r01688.vtc index fd0373b5a..bb4c92da3 100644 --- a/bin/varnishtest/tests/r01688.vtc +++ b/bin/varnishtest/tests/r01688.vtc @@ -18,7 +18,8 @@ varnish v1 -vcl+backend { sub vcl_synth { if (resp.status == 998) { - synthetic("this is the body of an included synthetic response"); + set resp.body = "this is the body of an " + + "included synthetic response"; return(deliver); } } diff --git a/bin/varnishtest/tests/r01838.vtc b/bin/varnishtest/tests/r01838.vtc index ce1f20b06..077851f70 100644 --- a/bin/varnishtest/tests/r01838.vtc +++ b/bin/varnishtest/tests/r01838.vtc @@ -14,7 +14,7 @@ varnish v1 -vcl+backend { sub vcl_synth { if (resp.status == 998) { - synthetic("synthetic body"); + set resp.body = "synthetic body"; return (deliver); } } diff --git a/bin/varnishtest/tests/r02429.vtc b/bin/varnishtest/tests/r02429.vtc index 81e42f0bd..3eb1b6ea1 100644 --- a/bin/varnishtest/tests/r02429.vtc +++ b/bin/varnishtest/tests/r02429.vtc @@ -6,7 +6,7 @@ server s1 { varnish v1 -arg "-s Transient=file,${tmpdir}/_.file,10m" -vcl+backend { sub vcl_backend_error { - synthetic("foo"); + set beresp.body = "foo"; return (deliver); } } -start diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index d2263dc37..913775778 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -467,8 +467,10 @@ hash_data(input) synthetic(STRING) ~~~~~~~~~~~~~~~~~ - Prepare a synthetic response body containing the *STRING*. Available in - ``vcl_synth`` and ``vcl_backend_error``. + Prepare a synthetic response body containing the *STRING*. Available + in ``vcl_synth`` and ``vcl_backend_error``. + + Identical to ``set resp.body`` / ``set beresp.body``. .. list above comes from struct action_table[] in vcc_action.c. From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:46 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:46 +0000 (UTC) Subject: [6.0] 15f5aa3d0 vtc sweep through tight backend workspace conditions Message-ID: <20180816085246.4F9119B1E1@lists.varnish-cache.org> commit 15f5aa3d0d2add1a71b8800ce76709f557e29f70 Author: Nils Goroll Date: Thu Apr 19 09:40:23 2018 +0200 vtc sweep through tight backend workspace conditions Ref: #2645 diff --git a/bin/varnishtest/tests/r02645.vtc b/bin/varnishtest/tests/r02645.vtc new file mode 100644 index 000000000..d66573747 --- /dev/null +++ b/bin/varnishtest/tests/r02645.vtc @@ -0,0 +1,25 @@ +varnishtest "sweep through tight backend workspace conditions" + +server s1 -repeat 100 { + rxreq + send "HTTP/1.1 200 OK\r\nTransfer-encoding: chunked\r\n\r\n00000004\r\n1234\r\n00000000\r\n\r\n" +} -start + +varnish v1 -vcl+backend { + import vtc; + import std; + sub vcl_recv { + return (pass); + } + sub vcl_backend_fetch { + vtc.workspace_alloc(backend, -4 * + (std.integer(bereq.xid, 1002) - 1000) / 2); + } +} -start + +client c1 -repeat 100 { + txreq -url "/" + # some responses will fail (503), some won't. All we care + # about here is the fact that we don't panic + rxresp +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:46 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:46 +0000 (UTC) Subject: [6.0] be5595b7e cache_vcl.c was getting too long, split along lines of "maintain list of VCLs" vs. "Do things with VCLs on list" Message-ID: <20180816085246.75B1B9B205@lists.varnish-cache.org> commit be5595b7ee1e7334b6bb6455a7e4c70fd84f0ecc Author: Poul-Henning Kamp Date: Thu Apr 19 07:43:55 2018 +0000 cache_vcl.c was getting too long, split along lines of "maintain list of VCLs" vs. "Do things with VCLs on list" diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 1e8640e07..9329f3674 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -44,6 +44,7 @@ varnishd_SOURCES = \ cache/cache_tcp_pool.c \ cache/cache_vary.c \ cache/cache_vcl.c \ + cache/cache_vcl_vrt.c \ cache/cache_vrt.c \ cache/cache_vrt_priv.c \ cache/cache_vrt_re.c \ @@ -125,6 +126,7 @@ noinst_HEADERS = \ cache/cache_pool.h \ cache/cache_tcp_pool.h \ cache/cache_transport.h \ + cache/cache_vcl.h \ cache/cache_vgz.h \ common/heritage.h \ common/vsmw.h \ diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 30adf54a0..abc519f39 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -42,49 +42,15 @@ #include "vcl.h" #include "cache_director.h" -#include "cache_backend.h" +#include "cache_vcl.h" #include "vcli_serve.h" -static const char * const VCL_TEMP_INIT = "init"; -static const char * const VCL_TEMP_COLD = "cold"; -static const char * const VCL_TEMP_WARM = "warm"; -static const char * const VCL_TEMP_BUSY = "busy"; -static const char * const VCL_TEMP_COOLING = "cooling"; -static const char * const VCL_TEMP_LABEL = "label"; - -/* - * NB: The COOLING temperature is neither COLD nor WARM. - * And LABEL is not a temperature, it's a different kind of VCL. - */ -#define VCL_WARM(v) ((v)->temp == VCL_TEMP_WARM || (v)->temp == VCL_TEMP_BUSY) -#define VCL_COLD(v) ((v)->temp == VCL_TEMP_INIT || (v)->temp == VCL_TEMP_COLD) - -struct vcl { - unsigned magic; -#define VCL_MAGIC 0x214188f2 - VTAILQ_ENTRY(vcl) list; - void *dlh; - const struct VCL_conf *conf; - char state[8]; - char *loaded_name; - unsigned busy; - unsigned discard; - const char *temp; - pthread_rwlock_t temp_rwl; - VTAILQ_HEAD(,director) director_list; - VTAILQ_HEAD(,vclref) ref_list; - int nrefs; - struct vcl *label; - int nlabels; -}; - -struct vclref { - unsigned magic; -#define VCLREF_MAGIC 0x47fb6848 - const struct vcl *vcl; - VTAILQ_ENTRY(vclref) list; - char desc[32]; -}; +const char * const VCL_TEMP_INIT = "init"; +const char * const VCL_TEMP_COLD = "cold"; +const char * const VCL_TEMP_WARM = "warm"; +const char * const VCL_TEMP_BUSY = "busy"; +const char * const VCL_TEMP_COOLING = "cooling"; +const char * const VCL_TEMP_LABEL = "label"; /* * XXX: Presently all modifications to this list happen from the @@ -93,8 +59,8 @@ struct vclref { static VTAILQ_HEAD(, vcl) vcl_head = VTAILQ_HEAD_INITIALIZER(vcl_head); -static struct lock vcl_mtx; -static struct vcl *vcl_active; /* protected by vcl_mtx */ +struct lock vcl_mtx; +struct vcl *vcl_active; /* protected by vcl_mtx */ static struct vrt_ctx ctx_cli; static unsigned handling_cli; @@ -171,7 +137,7 @@ vcl_send_event(VRT_CTX, enum vcl_event_e ev) /*--------------------------------------------------------------------*/ -static struct vcl * +struct vcl * vcl_find(const char *name) { struct vcl *vcl; @@ -225,37 +191,7 @@ VCL_Panic(struct vsb *vsb, const struct vcl *vcl) /*--------------------------------------------------------------------*/ -const char * -VCL_Return_Name(unsigned r) -{ - - switch (r) { -#define VCL_RET_MAC(l, U, B) \ - case VCL_RET_##U: \ - return(#l); -#include "tbl/vcl_returns.h" - default: - return (NULL); - } -} - -const char * -VCL_Method_Name(unsigned m) -{ - - switch (m) { -#define VCL_MET_MAC(func, upper, typ, bitmap) \ - case VCL_MET_##upper: \ - return (#upper); -#include "tbl/vcl_returns.h" - default: - return (NULL); - } -} - -/*--------------------------------------------------------------------*/ - -static void +void vcl_get(struct vcl **vcc, struct vcl *vcl) { AN(vcc); @@ -281,114 +217,8 @@ vcl_get(struct vcl **vcc, struct vcl *vcl) AZ(errno=pthread_rwlock_unlock(&(*vcc)->temp_rwl)); } -void -VCL_Refresh(struct vcl **vcc) -{ - if (*vcc == vcl_active) - return; - if (*vcc != NULL) - VCL_Rel(vcc); /* XXX: optimize locking */ - - while (vcl_active == NULL) - (void)usleep(100000); - - vcl_get(vcc, NULL); -} - -void -VCL_Ref(struct vcl *vcl) -{ - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); - assert(!VCL_COLD(vcl)); - AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); - Lck_Lock(&vcl_mtx); - assert(vcl->busy > 0); - vcl->busy++; - Lck_Unlock(&vcl_mtx); -} - -void -VCL_Rel(struct vcl **vcc) -{ - struct vcl *vcl; - - AN(*vcc); - vcl = *vcc; - *vcc = NULL; - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - Lck_Lock(&vcl_mtx); - assert(vcl->busy > 0); - vcl->busy--; - /* - * We do not garbage collect discarded VCL's here, that happens - * in VCL_Poll() which is called from the CLI thread. - */ - Lck_Unlock(&vcl_mtx); -} - /*--------------------------------------------------------------------*/ -int -VCL_AddDirector(struct vcl *vcl, struct director *d, const char *vcl_name) -{ - struct vsb *vsb; - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - AN(d->destroy); - - vsb = VSB_new_auto(); - AN(vsb); - VSB_printf(vsb, "%s.%s", VCL_Name(vcl), vcl_name); - AZ(VSB_finish(vsb)); - REPLACE((d->display_name), VSB_data(vsb)); - VSB_destroy(&vsb); - - AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); - if (vcl->temp == VCL_TEMP_COOLING) { - AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); - return (1); - } - - Lck_Lock(&vcl_mtx); - VTAILQ_INSERT_TAIL(&vcl->director_list, d, vcl_list); - d->vcl = vcl; - Lck_Unlock(&vcl_mtx); - - if (VCL_WARM(vcl)) - /* Only when adding backend to already warm VCL */ - VDI_Event(d, VCL_EVENT_WARM); - else if (vcl->temp != VCL_TEMP_INIT) - WRONG("Dynamic Backends can only be added to warm VCLs"); - AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); - - return (0); -} - -void -VCL_DelDirector(struct director *d) -{ - struct vcl *vcl; - - CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); - vcl = d->vcl; - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - Lck_Lock(&vcl_mtx); - VTAILQ_REMOVE(&vcl->director_list, d, vcl_list); - Lck_Unlock(&vcl_mtx); - - AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); - if (VCL_WARM(vcl)) - VDI_Event(d, VCL_EVENT_COLD); - AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); - AN(d->destroy); - REPLACE(d->display_name, NULL); - d->destroy(d); -} - static int vcl_iterdir(struct cli *cli, const char *pat, const struct vcl *vcl, vcl_be_func *func, void *priv) @@ -572,153 +402,6 @@ VCL_TestLoad(const char *fn) /*--------------------------------------------------------------------*/ -struct director * -VCL_DefaultDirector(const struct vcl *vcl) -{ - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); - return (*vcl->conf->default_director); -} - -const char * -VCL_Name(const struct vcl *vcl) -{ - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - return (vcl->loaded_name); -} - -const struct vrt_backend_probe * -VCL_DefaultProbe(const struct vcl *vcl) -{ - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); - return (vcl->conf->default_probe); -} - -/*-------------------------------------------------------------------- - * VRT apis relating to VCL's as VCLS. - */ - -void -VRT_count(VRT_CTX, unsigned u) -{ - - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); - CHECK_OBJ_NOTNULL(ctx->vcl->conf, VCL_CONF_MAGIC); - assert(u < ctx->vcl->conf->nref); - if (ctx->vsl != NULL) - VSLb(ctx->vsl, SLT_VCL_trace, "%s %u %u.%u.%u", - ctx->vcl->loaded_name, u, ctx->vcl->conf->ref[u].source, - ctx->vcl->conf->ref[u].line, ctx->vcl->conf->ref[u].pos); - else - VSL(SLT_VCL_trace, 0, "%s %u %u.%u.%u", - ctx->vcl->loaded_name, u, ctx->vcl->conf->ref[u].source, - ctx->vcl->conf->ref[u].line, ctx->vcl->conf->ref[u].pos); -} - -VCL_VCL -VRT_vcl_get(VRT_CTX, const char *name) -{ - VCL_VCL vcl; - - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - vcl = vcl_find(name); - AN(vcl); - Lck_Lock(&vcl_mtx); - vcl->nrefs++; - Lck_Unlock(&vcl_mtx); - return (vcl); -} - -void -VRT_vcl_rel(VRT_CTX, VCL_VCL vcl) -{ - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - AN(vcl); - Lck_Lock(&vcl_mtx); - vcl->nrefs--; - Lck_Unlock(&vcl_mtx); -} - -void -VRT_vcl_select(VRT_CTX, VCL_VCL vcl) -{ - struct req *req = ctx->req; - - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - VCL_Rel(&req->vcl); - vcl_get(&req->vcl, vcl); - /* XXX: better logging */ - VSLb(ctx->req->vsl, SLT_Debug, "Now using %s VCL", vcl->loaded_name); -} - -struct vclref * -VRT_ref_vcl(VRT_CTX, const char *desc) -{ - struct vcl *vcl; - struct vclref* ref; - - ASSERT_CLI(); - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - AN(desc); - AN(*desc); - - vcl = ctx->vcl; - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - assert(VCL_WARM(vcl)); - - ALLOC_OBJ(ref, VCLREF_MAGIC); - AN(ref); - ref->vcl = vcl; - bprintf(ref->desc, "%s", desc); - - Lck_Lock(&vcl_mtx); - VTAILQ_INSERT_TAIL(&vcl->ref_list, ref, list); - vcl->nrefs++; - Lck_Unlock(&vcl_mtx); - - return (ref); -} - -void -VRT_rel_vcl(VRT_CTX, struct vclref **refp) -{ - struct vcl *vcl; - struct vclref *ref; - - AN(refp); - ref = *refp; - *refp = NULL; - - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - CHECK_OBJ_NOTNULL(ref, VCLREF_MAGIC); - - vcl = ctx->vcl; - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); - assert(vcl == ref->vcl); - - /* NB: A VCL may be released by a VMOD at any time, but it must happen - * after a warmup and before the end of a cooldown. The release may or - * may not happen while the same thread holds the temperature lock, so - * instead we check that all references are gone in VCL_Nuke. - */ - - Lck_Lock(&vcl_mtx); - assert(!VTAILQ_EMPTY(&vcl->ref_list)); - VTAILQ_REMOVE(&vcl->ref_list, ref, list); - vcl->nrefs--; - /* No garbage collection here, for the same reasons as in VCL_Rel. */ - Lck_Unlock(&vcl_mtx); - - FREE_OBJ(ref); -} - -/*--------------------------------------------------------------------*/ - static void vcl_print_refs(VRT_CTX) { @@ -1100,92 +783,6 @@ vcl_cli_show(struct cli *cli, const char * const *av, void *priv) } } -/*-------------------------------------------------------------------- - * Method functions to call into VCL programs. - * - * Either the request or busyobject must be specified, but not both. - * The workspace argument is where random VCL stuff gets space from. - */ - -static void -vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, - void *specific, unsigned method, vcl_func_f *func) -{ - uintptr_t aws; - struct vsl_log *vsl = NULL; - struct vrt_ctx ctx; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - INIT_OBJ(&ctx, VRT_CTX_MAGIC); - if (req != NULL) { - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(req->vcl, VCL_MAGIC); - vsl = req->vsl; - ctx.vcl = req->vcl; - ctx.http_req = req->http; - ctx.http_req_top = req->top->http; - ctx.http_resp = req->resp; - ctx.req = req; - ctx.sp = req->sp; - ctx.now = req->t_prev; - ctx.ws = req->ws; - } - if (bo != NULL) { - if (req) - assert(method == VCL_MET_PIPE); - CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); - CHECK_OBJ_NOTNULL(bo->vcl, VCL_MAGIC); - vsl = bo->vsl; - ctx.vcl = bo->vcl; - ctx.http_bereq = bo->bereq; - ctx.http_beresp = bo->beresp; - ctx.bo = bo; - ctx.sp = bo->sp; - ctx.now = bo->t_prev; - ctx.ws = bo->ws; - } - assert(ctx.now != 0); - ctx.syntax = ctx.vcl->conf->syntax; - ctx.vsl = vsl; - ctx.specific = specific; - ctx.method = method; - wrk->handling = 0; - ctx.handling = &wrk->handling; - aws = WS_Snapshot(wrk->aws); - wrk->cur_method = method; - wrk->seen_methods |= method; - AN(vsl); - VSLb(vsl, SLT_VCL_call, "%s", VCL_Method_Name(method)); - func(&ctx); - VSLb(vsl, SLT_VCL_return, "%s", VCL_Return_Name(wrk->handling)); - wrk->cur_method |= 1; // Magic marker - if (wrk->handling == VCL_RET_FAIL) - wrk->stats->vcl_fail++; - - /* - * VCL/Vmods are not allowed to make permanent allocations from - * wrk->aws, but they can reserve and return from it. - */ - assert(aws == WS_Snapshot(wrk->aws)); -} - -#define VCL_MET_MAC(func, upper, typ, bitmap) \ -void \ -VCL_##func##_method(struct vcl *vcl, struct worker *wrk, \ - struct req *req, struct busyobj *bo, void *specific) \ -{ \ - \ - CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); \ - CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); \ - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); \ - vcl_call_method(wrk, req, bo, specific, \ - VCL_MET_ ## upper, vcl->conf->func##_func); \ - AN((1U << wrk->handling) & bitmap); \ -} - -#include "tbl/vcl_returns.h" - /*--------------------------------------------------------------------*/ static struct cli_proto vcl_cmds[] = { diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h new file mode 100644 index 000000000..87433afe3 --- /dev/null +++ b/bin/varnishd/cache/cache_vcl.h @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2016 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +struct vcl { + unsigned magic; +#define VCL_MAGIC 0x214188f2 + VTAILQ_ENTRY(vcl) list; + void *dlh; + const struct VCL_conf *conf; + char state[8]; + char *loaded_name; + unsigned busy; + unsigned discard; + const char *temp; + pthread_rwlock_t temp_rwl; + VTAILQ_HEAD(,director) director_list; + VTAILQ_HEAD(,vclref) ref_list; + int nrefs; + struct vcl *label; + int nlabels; +}; + +struct vclref { + unsigned magic; +#define VCLREF_MAGIC 0x47fb6848 + const struct vcl *vcl; + VTAILQ_ENTRY(vclref) list; + char desc[32]; +}; + +extern struct lock vcl_mtx; +extern struct vcl *vcl_active; /* protected by vcl_mtx */ +struct vcl *vcl_find(const char *); +void vcl_get(struct vcl **, struct vcl *); + +extern const char * const VCL_TEMP_INIT; +extern const char * const VCL_TEMP_COLD; +extern const char * const VCL_TEMP_WARM; +extern const char * const VCL_TEMP_BUSY; +extern const char * const VCL_TEMP_COOLING; +extern const char * const VCL_TEMP_LABEL; + +/* + * NB: The COOLING temperature is neither COLD nor WARM. + * And LABEL is not a temperature, it's a different kind of VCL. + */ +#define VCL_WARM(v) ((v)->temp == VCL_TEMP_WARM || (v)->temp == VCL_TEMP_BUSY) +#define VCL_COLD(v) ((v)->temp == VCL_TEMP_INIT || (v)->temp == VCL_TEMP_COLD) + + diff --git a/bin/varnishd/cache/cache_vcl_vrt.c b/bin/varnishd/cache/cache_vcl_vrt.c new file mode 100644 index 000000000..484c14b4a --- /dev/null +++ b/bin/varnishd/cache/cache_vcl_vrt.c @@ -0,0 +1,415 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2016 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "config.h" + +#include +#include +#include + +#include "cache_varnishd.h" + +#include "vcl.h" + +#include "cache_director.h" +#include "cache_vcl.h" + +/*--------------------------------------------------------------------*/ + +const char * +VCL_Return_Name(unsigned r) +{ + + switch (r) { +#define VCL_RET_MAC(l, U, B) \ + case VCL_RET_##U: \ + return(#l); +#include "tbl/vcl_returns.h" + default: + return (NULL); + } +} + +const char * +VCL_Method_Name(unsigned m) +{ + + switch (m) { +#define VCL_MET_MAC(func, upper, typ, bitmap) \ + case VCL_MET_##upper: \ + return (#upper); +#include "tbl/vcl_returns.h" + default: + return (NULL); + } +} + +/*--------------------------------------------------------------------*/ + +void +VCL_Refresh(struct vcl **vcc) +{ + if (*vcc == vcl_active) + return; + if (*vcc != NULL) + VCL_Rel(vcc); /* XXX: optimize locking */ + + while (vcl_active == NULL) + (void)usleep(100000); + + vcl_get(vcc, NULL); +} + +void +VCL_Ref(struct vcl *vcl) +{ + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); + assert(!VCL_COLD(vcl)); + AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); + Lck_Lock(&vcl_mtx); + assert(vcl->busy > 0); + vcl->busy++; + Lck_Unlock(&vcl_mtx); +} + +void +VCL_Rel(struct vcl **vcc) +{ + struct vcl *vcl; + + AN(*vcc); + vcl = *vcc; + *vcc = NULL; + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + Lck_Lock(&vcl_mtx); + assert(vcl->busy > 0); + vcl->busy--; + /* + * We do not garbage collect discarded VCL's here, that happens + * in VCL_Poll() which is called from the CLI thread. + */ + Lck_Unlock(&vcl_mtx); +} + +/*--------------------------------------------------------------------*/ + +int +VCL_AddDirector(struct vcl *vcl, struct director *d, const char *vcl_name) +{ + struct vsb *vsb; + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + AN(d->destroy); + + vsb = VSB_new_auto(); + AN(vsb); + VSB_printf(vsb, "%s.%s", VCL_Name(vcl), vcl_name); + AZ(VSB_finish(vsb)); + REPLACE((d->display_name), VSB_data(vsb)); + VSB_destroy(&vsb); + + AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); + if (vcl->temp == VCL_TEMP_COOLING) { + AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); + return (1); + } + + Lck_Lock(&vcl_mtx); + VTAILQ_INSERT_TAIL(&vcl->director_list, d, vcl_list); + d->vcl = vcl; + Lck_Unlock(&vcl_mtx); + + if (VCL_WARM(vcl)) + /* Only when adding backend to already warm VCL */ + VDI_Event(d, VCL_EVENT_WARM); + else if (vcl->temp != VCL_TEMP_INIT) + WRONG("Dynamic Backends can only be added to warm VCLs"); + AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); + + return (0); +} + +void +VCL_DelDirector(struct director *d) +{ + struct vcl *vcl; + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + vcl = d->vcl; + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + Lck_Lock(&vcl_mtx); + VTAILQ_REMOVE(&vcl->director_list, d, vcl_list); + Lck_Unlock(&vcl_mtx); + + AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl)); + if (VCL_WARM(vcl)) + VDI_Event(d, VCL_EVENT_COLD); + AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl)); + AN(d->destroy); + REPLACE(d->display_name, NULL); + d->destroy(d); +} + +/*--------------------------------------------------------------------*/ + +struct director * +VCL_DefaultDirector(const struct vcl *vcl) +{ + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); + return (*vcl->conf->default_director); +} + +const char * +VCL_Name(const struct vcl *vcl) +{ + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + return (vcl->loaded_name); +} + +const struct vrt_backend_probe * +VCL_DefaultProbe(const struct vcl *vcl) +{ + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); + return (vcl->conf->default_probe); +} + +/*-------------------------------------------------------------------- + * VRT apis relating to VCL's as VCLS. + */ + +void +VRT_count(VRT_CTX, unsigned u) +{ + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC); + CHECK_OBJ_NOTNULL(ctx->vcl->conf, VCL_CONF_MAGIC); + assert(u < ctx->vcl->conf->nref); + if (ctx->vsl != NULL) + VSLb(ctx->vsl, SLT_VCL_trace, "%s %u %u.%u.%u", + ctx->vcl->loaded_name, u, ctx->vcl->conf->ref[u].source, + ctx->vcl->conf->ref[u].line, ctx->vcl->conf->ref[u].pos); + else + VSL(SLT_VCL_trace, 0, "%s %u %u.%u.%u", + ctx->vcl->loaded_name, u, ctx->vcl->conf->ref[u].source, + ctx->vcl->conf->ref[u].line, ctx->vcl->conf->ref[u].pos); +} + +VCL_VCL +VRT_vcl_get(VRT_CTX, const char *name) +{ + VCL_VCL vcl; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + vcl = vcl_find(name); + AN(vcl); + Lck_Lock(&vcl_mtx); + vcl->nrefs++; + Lck_Unlock(&vcl_mtx); + return (vcl); +} + +void +VRT_vcl_rel(VRT_CTX, VCL_VCL vcl) +{ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + AN(vcl); + Lck_Lock(&vcl_mtx); + vcl->nrefs--; + Lck_Unlock(&vcl_mtx); +} + +void +VRT_vcl_select(VRT_CTX, VCL_VCL vcl) +{ + struct req *req = ctx->req; + + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + VCL_Rel(&req->vcl); + vcl_get(&req->vcl, vcl); + /* XXX: better logging */ + VSLb(ctx->req->vsl, SLT_Debug, "Now using %s VCL", vcl->loaded_name); +} + +struct vclref * +VRT_ref_vcl(VRT_CTX, const char *desc) +{ + struct vcl *vcl; + struct vclref* ref; + + ASSERT_CLI(); + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + AN(desc); + AN(*desc); + + vcl = ctx->vcl; + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + assert(VCL_WARM(vcl)); + + ALLOC_OBJ(ref, VCLREF_MAGIC); + AN(ref); + ref->vcl = vcl; + bprintf(ref->desc, "%s", desc); + + Lck_Lock(&vcl_mtx); + VTAILQ_INSERT_TAIL(&vcl->ref_list, ref, list); + vcl->nrefs++; + Lck_Unlock(&vcl_mtx); + + return (ref); +} + +void +VRT_rel_vcl(VRT_CTX, struct vclref **refp) +{ + struct vcl *vcl; + struct vclref *ref; + + AN(refp); + ref = *refp; + *refp = NULL; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(ref, VCLREF_MAGIC); + + vcl = ctx->vcl; + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + assert(vcl == ref->vcl); + + /* NB: A VCL may be released by a VMOD at any time, but it must happen + * after a warmup and before the end of a cooldown. The release may or + * may not happen while the same thread holds the temperature lock, so + * instead we check that all references are gone in VCL_Nuke. + */ + + Lck_Lock(&vcl_mtx); + assert(!VTAILQ_EMPTY(&vcl->ref_list)); + VTAILQ_REMOVE(&vcl->ref_list, ref, list); + vcl->nrefs--; + /* No garbage collection here, for the same reasons as in VCL_Rel. */ + Lck_Unlock(&vcl_mtx); + + FREE_OBJ(ref); +} + +/*-------------------------------------------------------------------- + * Method functions to call into VCL programs. + * + * Either the request or busyobject must be specified, but not both. + * The workspace argument is where random VCL stuff gets space from. + */ + +static void +vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, + void *specific, unsigned method, vcl_func_f *func) +{ + uintptr_t aws; + struct vsl_log *vsl = NULL; + struct vrt_ctx ctx; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + INIT_OBJ(&ctx, VRT_CTX_MAGIC); + if (req != NULL) { + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(req->vcl, VCL_MAGIC); + vsl = req->vsl; + ctx.vcl = req->vcl; + ctx.http_req = req->http; + ctx.http_req_top = req->top->http; + ctx.http_resp = req->resp; + ctx.req = req; + ctx.sp = req->sp; + ctx.now = req->t_prev; + ctx.ws = req->ws; + } + if (bo != NULL) { + if (req) + assert(method == VCL_MET_PIPE); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + CHECK_OBJ_NOTNULL(bo->vcl, VCL_MAGIC); + vsl = bo->vsl; + ctx.vcl = bo->vcl; + ctx.http_bereq = bo->bereq; + ctx.http_beresp = bo->beresp; + ctx.bo = bo; + ctx.sp = bo->sp; + ctx.now = bo->t_prev; + ctx.ws = bo->ws; + } + assert(ctx.now != 0); + ctx.syntax = ctx.vcl->conf->syntax; + ctx.vsl = vsl; + ctx.specific = specific; + ctx.method = method; + wrk->handling = 0; + ctx.handling = &wrk->handling; + aws = WS_Snapshot(wrk->aws); + wrk->cur_method = method; + wrk->seen_methods |= method; + AN(vsl); + VSLb(vsl, SLT_VCL_call, "%s", VCL_Method_Name(method)); + func(&ctx); + VSLb(vsl, SLT_VCL_return, "%s", VCL_Return_Name(wrk->handling)); + wrk->cur_method |= 1; // Magic marker + if (wrk->handling == VCL_RET_FAIL) + wrk->stats->vcl_fail++; + + /* + * VCL/Vmods are not allowed to make permanent allocations from + * wrk->aws, but they can reserve and return from it. + */ + assert(aws == WS_Snapshot(wrk->aws)); +} + +#define VCL_MET_MAC(func, upper, typ, bitmap) \ +void \ +VCL_##func##_method(struct vcl *vcl, struct worker *wrk, \ + struct req *req, struct busyobj *bo, void *specific) \ +{ \ + \ + CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); \ + CHECK_OBJ_NOTNULL(vcl->conf, VCL_CONF_MAGIC); \ + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); \ + vcl_call_method(wrk, req, bo, specific, \ + VCL_MET_ ## upper, vcl->conf->func##_func); \ + AN((1U << wrk->handling) & bitmap); \ +} + +#include "tbl/vcl_returns.h" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:46 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:46 +0000 (UTC) Subject: [6.0] 466c874d5 Sync VJSN tests with Nicolas Seriots master list Message-ID: <20180816085246.A408C9B221@lists.varnish-cache.org> commit 466c874d5a595bcc44e73bf2e85a5f71c4934af2 Author: Poul-Henning Kamp Date: Thu Apr 19 08:15:19 2018 +0000 Sync VJSN tests with Nicolas Seriots master list diff --git a/lib/libvarnish/vjsn.c b/lib/libvarnish/vjsn.c index 8f08e745e..d1b34080d 100644 --- a/lib/libvarnish/vjsn.c +++ b/lib/libvarnish/vjsn.c @@ -520,40 +520,45 @@ vjsn_dump(const struct vjsn *js, FILE *fo) * * And run this python in test_parsing: - import glob - - def emit(fin): - if fin in skip: - return - x = bytearray(open(fin).read()) - if 0 in x: - return - if len(x) > 1000: - return - t = '\t"' - for i in x: - t += "\\x%02x" % i - if len(t) > 64: - print(t + '"') - t = '\t"' - print(t + '",') - - print("const char *good[] = {") - for f in glob.glob("y_*"): - emit(f) - print("\tNULL") - print("};") - - print("const char *bad[] = {") - for f in glob.glob("n_*"): - emit(f) - print("\tNULL") - print("};") - -*/ + import glob + + skip = {} + + def emit(fin): + if fin in skip: + return + x = bytearray(open(fin).read()) + if 0 in x: + return + if len(x) > 1000: + return + t = '\t"' + for i in x: + t += "\\x%02x" % i + if len(t) > 64: + print(t + '"') + t = '\t"' + print(t + '",') + + print("const char *good[] = {") + l = list(glob.glob("y_*")) + l.sort() + for f in l: + emit(f) + print("\tNULL") + print("};") + + print("const char *bad[] = {") + l = list(glob.glob("n_*")) + l.sort() + for f in l: + emit(f) + print("\tNULL") + print("};") + + */ static const char *good[] = { - "\x5b\x31\x32\x33\x65\x36\x35\x5d", "\x5b\x5b\x5d\x20\x20\x20\x5d", "\x5b\x22\x22\x5d", "\x5b\x5d", @@ -567,6 +572,7 @@ static const char *good[] = { "\x5b\x31\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c" "\x6c\x2c\x32\x5d", "\x5b\x32\x5d\x20", + "\x5b\x31\x32\x33\x65\x36\x35\x5d", "\x5b\x30\x65\x2b\x31\x5d", "\x5b\x30\x65\x31\x5d", "\x5b\x20\x34\x5d", @@ -620,10 +626,10 @@ static const char *good[] = { "\x34\x33\x35\x5c\x75\x30\x34\x33\x61\x5c\x75\x30\x34\x33\x65\x5c" "\x75\x30\x34\x33\x66\x5c\x75\x30\x34\x33\x30\x22\x20\x7d", "\x7b\x0a\x22\x61\x22\x3a\x20\x22\x62\x22\x0a\x7d", - "\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d" - "", "\x5b\x22\x5c\x75\x30\x30\x36\x30\x5c\x75\x30\x31\x32\x61\x5c\x75" "\x31\x32\x41\x42\x22\x5d", + "\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d" + "", "\x5b\x22\x5c\x75\x64\x38\x33\x64\x5c\x75\x64\x65\x33\x39\x5c\x75" "\x64\x38\x33\x64\x5c\x75\x64\x63\x38\x64\x22\x5d", "\x5b\x22\x5c\x22\x5c\x5c\x5c\x2f\x5c\x62\x5c\x66\x5c\x6e\x5c\x72" @@ -637,17 +643,17 @@ static const char *good[] = { "\x5b\x22\x5c\x75\x30\x30\x31\x32\x22\x5d", "\x5b\x22\x5c\x75\x46\x46\x46\x46\x22\x5d", "\x5b\x22\x61\x73\x64\x22\x5d", - "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22" - "\x5d", "\x5b\x20\x22\x61\x73\x64\x22\x5d", "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x46\x22\x5d" "", + "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22" + "\x5d", "\x5b\x22\xf4\x8f\xbf\xbf\x22\x5d", - "\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d", "\x5b\x22\xef\xbf\xbf\x22\x5d", "\x5b\x22\x5c\x75\x30\x30\x30\x30\x22\x5d", "\x5b\x22\x5c\x75\x30\x30\x32\x63\x22\x5d", "\x5b\x22\xcf\x80\x22\x5d", + "\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d", "\x5b\x22\x61\x73\x64\x20\x22\x5d", "\x22\x20\x22", "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x31\x65\x22\x5d" @@ -668,12 +674,12 @@ static const char *good[] = { "", "\x5b\x22\x5c\x75\x44\x38\x33\x46\x5c\x75\x44\x46\x46\x45\x22\x5d" "", - "\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d", "\x5b\x22\x5c\x75\x32\x30\x30\x42\x22\x5d", "\x5b\x22\x5c\x75\x32\x30\x36\x34\x22\x5d", "\x5b\x22\x5c\x75\x46\x44\x44\x30\x22\x5d", "\x5b\x22\x5c\x75\x46\x46\x46\x45\x22\x5d", "\x5b\x22\x5c\x75\x30\x30\x32\x32\x22\x5d", + "\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d", "\x5b\x22\x61\x7f\x61\x22\x5d", "\x66\x61\x6c\x73\x65", "\x34\x32", @@ -698,9 +704,9 @@ static const char *bad[] = { "\x5b\x22\x78\x22\x5d\x5d", "\x5b\x22\x22\x2c\x5d", "\x5b\x22\x78\x22", - "\x5b\xff\x5d", "\x5b\x78", "\x5b\x33\x5b\x34\x5d\x5d", + "\x5b\xff\x5d", "\x5b\x31\x3a\x32\x5d", "\x5b\x2c\x5d", "\x5b\x2d\x5d", @@ -776,6 +782,7 @@ static const char *bad[] = { "\x7b\xf0\x9f\x87\xa8\xf0\x9f\x87\xad\x7d", "\x7b\x22\x61\x22\x3a\x22\x61\x22\x20\x31\x32\x33\x7d", "\x7b\x6b\x65\x79\x3a\x20\x27\x76\x61\x6c\x75\x65\x27\x7d", + "\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d", "\x7b\x22\x61\x22\x20\x62\x7d", "\x7b\x3a\x22\x62\x22\x7d", "\x7b\x22\x61\x22\x20\x22\x62\x22\x7d", @@ -783,7 +790,6 @@ static const char *bad[] = { "\x7b\x22\x61\x22", "\x7b\x31\x3a\x31\x7d", "\x7b\x39\x39\x39\x39\x45\x39\x39\x39\x39\x3a\x31\x7d", - "\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d", "\x7b\x6e\x75\x6c\x6c\x3a\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x3a" "\x6e\x75\x6c\x6c\x7d", "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x2c\x2c\x2c\x2c\x7d", From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:46 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:46 +0000 (UTC) Subject: [6.0] 6ca2ff8b3 Whitespace ocd Message-ID: <20180816085246.BDB8E9B237@lists.varnish-cache.org> commit 6ca2ff8b3a76744360953cb9e0339509eae69cdf Author: Poul-Henning Kamp Date: Fri Apr 20 09:54:24 2018 +0000 Whitespace ocd Conflicts: doc/sphinx/reference/vcl_var.rst (beresp.filters) diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 6df36351e..30fee32d7 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -43,7 +43,7 @@ Without PROXY protocol:: client server remote local - v v + v v CLIENT ------------ VARNISHD @@ -71,18 +71,18 @@ local.endpoint ``VCL >= 4.1`` Type: STRING Readable from: client, backend - + The address of the '-a' socket the session was accepted on. If the argument was `-a foo=:81` this would be ":81" - + local.socket ``VCL >= 4.1`` Type: STRING Readable from: client, backend - + The name of the '-a' socket the session was accepted on. If the argument was `-a foo=:81` this would be "foo". @@ -99,7 +99,7 @@ remote.ip The IP address of the other end of the TCP connection. This can either be the clients IP, or the outgoing IP of a proxy server. - + If the connection is a UNIX domain socket, the value will be `0.0.0.0:0` @@ -109,7 +109,7 @@ client.ip Readable from: client, backend - + The client's IP address, either the same as `local.ip` or what the PROXY protocol told us. @@ -121,7 +121,7 @@ client.identity Writable from: client - + Identification of the client, used to load balance in the client director. Defaults to `client.ip` @@ -136,28 +136,28 @@ server.ip Readable from: client, backend - + The IP address of the socket on which the client connection was received, either the same as `server.ip` or what the PROXY protocol told us. - + server.hostname Type: STRING Readable from: all - + The host name of the server, as returned by the `gethostname(3)` system function. - + server.identity Type: STRING Readable from: all - + The identity of the server, as set by the `-i` parameter. If an `-i` parameter is not passed to varnishd, the return @@ -176,10 +176,10 @@ req Readable from: client - + The entire request HTTP data structure. Mostly useful for passing to VMODs. - + req.method @@ -189,9 +189,9 @@ req.method Writable from: client - + The request method (e.g. "GET", "HEAD", ...) - + req.hash @@ -199,11 +199,11 @@ req.hash Readable from: vcl_hit, vcl_miss, vcl_pass, vcl_purge, vcl_deliver - + The hash key of this request. Mostly useful for passing to VMODs, but can also be useful for debugging hit/miss status. - + req.url @@ -213,9 +213,9 @@ req.url Writable from: client - + The requested URL, for instance "/robots.txt". - + req.proto ``VCL <= 4.0`` @@ -227,7 +227,7 @@ req.proto ``VCL <= 4.0`` The HTTP protocol version used by the client, usually "HTTP/1.1" or "HTTP/2.0". - + req.proto ``VCL >= 4.1`` Type: STRING @@ -236,7 +236,7 @@ req.proto ``VCL >= 4.1`` The HTTP protocol version used by the client, usually "HTTP/1.1" or "HTTP/2.0". - + req.http.* @@ -248,12 +248,12 @@ req.http.* Unsetable from: client - + The headers of request, things like `req.http.date`. The RFCs allow multiple headers with the same name, and both `set` and `unset` will remove *all* headers with the name given. - + req.restarts @@ -261,9 +261,9 @@ req.restarts Readable from: client - + A count of how many times this request has been restarted. - + req.storage @@ -273,16 +273,16 @@ req.storage Writable from: client - + The storage backend to use to save this request body. - + req.esi_level Type: INT Readable from: client - + A count of how many levels of ESI requests we're currently at. req.ttl @@ -293,16 +293,16 @@ req.ttl Writable from: client - + Upper limit on the object age for cache lookups to return hit. - + Usage of req.ttl should be replaced with a check on obj.ttl in vcl_hit, returning miss when needed, but this currently hits bug #1799, so an additional workaround is required. - + Deprecated and scheduled for removal with varnish release 7. - + req.xid @@ -330,10 +330,10 @@ req.can_gzip Type: BOOL Readable from: client - + True if the client provided `gzip` or `x-gzip` in the `Accept-Encoding` header. - + req.backend_hint @@ -349,7 +349,7 @@ req.backend_hint or the director otherwise. When used in string context, returns the name of the director or backend, respectively. - + req.hash_ignore_busy @@ -365,7 +365,7 @@ req.hash_ignore_busy You only want to do this when you have two server looking up content sideways from each other to avoid deadlocks. - + req.hash_always_miss @@ -382,7 +382,7 @@ req.hash_always_miss This is useful to force-update the cache without invalidating existing entries in case the fetch fails. - + req_top.method @@ -393,39 +393,39 @@ req_top.method The request method of the top-level request in a tree of ESI requests. (e.g. "GET", "HEAD"). Identical to req.method in non-ESI requests. - + req_top.url Type: STRING Readable from: client - + The requested URL of the top-level request in a tree of ESI requests. Identical to req.url in non-ESI requests. - + req_top.http.* Type: HEADER Readable from: client - + HTTP headers of the top-level request in a tree of ESI requests. Identical to req.http. in non-ESI requests. - + req_top.proto Type: STRING Readable from: client - + HTTP protocol version of the top-level request in a tree of ESI requests. Identical to req.proto in non-ESI requests. - + bereq ~~~~~ @@ -445,25 +445,25 @@ bereq The entire backend request HTTP data structure. Mostly useful as argument to VMODs. - + bereq.xid Type: STRING Readable from: backend - + Unique ID of this request. - + bereq.retries Type: INT Readable from: backend - + A count of how many times this request has been retried. - + bereq.backend @@ -472,21 +472,21 @@ bereq.backend Readable from: vcl_pipe, backend Writable from: vcl_pipe, backend - + This is the backend or director we attempt to fetch from. When set to a director, reading this variable returns an actual backend if the director has resolved immediately, or the director otherwise. When used in string context, returns the name of the director or backend, respectively. - + bereq.body Type: BODY Unsetable from: vcl_backend_fetch - + The request body, only present on `pass` requests. Unset will also remove `bereq.http.Content-Length`. @@ -496,9 +496,9 @@ bereq.hash Type: BLOB Readable from: vcl_pipe, backend - + The hash key of this request, a copy of `req.hash`. - + bereq.method @@ -507,11 +507,11 @@ bereq.method Readable from: vcl_pipe, backend Writable from: vcl_pipe, backend - + The request type (e.g. "GET", "HEAD"). Regular (non-pipe, non-pass) fetches are always "GET" - + bereq.url @@ -522,7 +522,7 @@ bereq.url Writable from: vcl_pipe, backend The requested URL, copied from `req.url` - + bereq.proto ``VCL <= 4.0`` @@ -531,19 +531,19 @@ bereq.proto ``VCL <= 4.0`` Readable from: vcl_pipe, backend Writable from: vcl_pipe, backend - + The HTTP protocol version, "HTTP/1.1" unless a pass or pipe request has "HTTP/1.0" in `req.proto` - + bereq.proto ``VCL >= 4.1`` Type: STRING Readable from: vcl_pipe, backend - + The HTTP protocol version, "HTTP/1.1" unless a pass or pipe request has "HTTP/1.0" in `req.proto` - + bereq.http.* @@ -556,7 +556,7 @@ bereq.http.* Unsetable from: vcl_pipe, backend The headers to be sent to the backend. - + bereq.uncacheable @@ -564,10 +564,10 @@ bereq.uncacheable Readable from: backend - + Indicates whether this request is uncacheable due to a `pass` in the client side or a hit on an hit-for-pass object. - + bereq.connect_timeout @@ -576,10 +576,10 @@ bereq.connect_timeout Readable from: vcl_pipe, backend Writable from: vcl_pipe, backend - + The time in seconds to wait for a backend connection to be established. - + bereq.first_byte_timeout @@ -588,10 +588,10 @@ bereq.first_byte_timeout Readable from: backend Writable from: backend - + The time in seconds to wait getting the first byte back from the backend. Not available in pipe mode. - + bereq.between_bytes_timeout @@ -600,17 +600,17 @@ bereq.between_bytes_timeout Readable from: backend Writable from: backend - + The time in seconds to wait between each received byte from the backend. Not available in pipe mode. - + bereq.is_bgfetch Type: BOOL Readable from: backend - + True for fetches where the client got a hit on an object in grace, and this fetch was kicked of in the background to get a fresh copy. @@ -635,7 +635,7 @@ beresp.body Type: BODY Writable from: vcl_backend_error - + For producing a synthetic body. beresp.proto ``VCL <= 4.0`` @@ -647,7 +647,7 @@ beresp.proto ``VCL <= 4.0`` Writable from: vcl_backend_response, vcl_backend_error The HTTP protocol version the backend replied with. - + beresp.proto ``VCL >= 4.1`` Type: STRING @@ -655,7 +655,7 @@ beresp.proto ``VCL >= 4.1`` Readable from: vcl_backend_response, vcl_backend_error The HTTP protocol version the backend replied with. - + beresp.status @@ -666,7 +666,7 @@ beresp.status Writable from: vcl_backend_response, vcl_backend_error The HTTP status code returned by the server. - + Status codes on the form XXYZZ can be set where XXYZZ is less than 65536 and Y is [1...9]. Only YZZ will be sent back to clients. @@ -709,7 +709,7 @@ beresp.do_esi Set it to true to parse the object for ESI directives. Will only be honored if req.esi is true. - + beresp.do_stream @@ -768,7 +768,7 @@ beresp.was_304 Readable from: vcl_backend_response, vcl_backend_error - + When `true` this indicates that we got a 304 response to our conditional fetch from the backend and turned that into `beresp.status = 200` @@ -782,14 +782,14 @@ beresp.uncacheable Writable from: vcl_backend_response, vcl_backend_error Inherited from bereq.uncacheable, see there. - + Setting this variable makes the object uncacheable. This may may produce a hit-for-miss object in the cache. - + Clearing the variable has no effect and will log the warning "Ignoring attempt to reset beresp.uncacheable". - + beresp.ttl @@ -800,7 +800,7 @@ beresp.ttl Writable from: vcl_backend_response, vcl_backend_error The object's remaining time to live, in seconds. - + beresp.age @@ -809,7 +809,7 @@ beresp.age Readable from: vcl_backend_response, vcl_backend_error The age of the object. - + beresp.grace @@ -820,7 +820,7 @@ beresp.grace Writable from: vcl_backend_response, vcl_backend_error Set to a period to enable grace. - + beresp.keep @@ -831,13 +831,13 @@ beresp.keep Writable from: vcl_backend_response, vcl_backend_error Set to a period to enable conditional backend requests. - + The keep time is cache lifetime in addition to the ttl. - + Objects with ttl expired but with keep time left may be used to issue conditional (If-Modified-Since / If-None-Match) requests to the backend to refresh them. - + beresp.backend @@ -849,7 +849,7 @@ beresp.backend was set to a director, this will be the backend selected by the director. When used in string context, returns its name. - + beresp.backend.name @@ -859,7 +859,7 @@ beresp.backend.name Name of the backend this response was fetched from. Same as beresp.backend. - + beresp.backend.ip ``VCL <= 4.0`` @@ -877,7 +877,7 @@ beresp.storage Writable from: vcl_backend_response, vcl_backend_error - + The storage backend to use to save this object. beresp.storage_hint ``VCL <= 4.0`` @@ -888,10 +888,10 @@ beresp.storage_hint ``VCL <= 4.0`` Writable from: vcl_backend_response, vcl_backend_error - + Deprecated since varnish 5.1 and discontinued since VCL 4.1 (varnish 6.0). Use beresp.storage instead. - + Hint to Varnish that you want to save this object to a particular storage backend. @@ -907,7 +907,7 @@ obj.proto Readable from: vcl_hit The HTTP protocol version stored in the object. - + obj.status @@ -915,9 +915,9 @@ obj.status Readable from: vcl_hit - + The HTTP status code stored in the object. - + obj.reason @@ -925,9 +925,9 @@ obj.reason Readable from: vcl_hit - + The HTTP reason phrase stored in the object. - + obj.hits @@ -935,11 +935,11 @@ obj.hits Readable from: vcl_hit, vcl_deliver - + The count of cache-hits on this object. In `vcl_deliver` a value of 0 indicates a cache miss. - + obj.http.* @@ -948,7 +948,7 @@ obj.http.* Readable from: vcl_hit The HTTP headers stored in the object. - + obj.ttl @@ -957,7 +957,7 @@ obj.ttl Readable from: vcl_hit, vcl_deliver The object's remaining time to live, in seconds. - + obj.age @@ -966,7 +966,7 @@ obj.age Readable from: vcl_hit, vcl_deliver The age of the object. - + obj.grace @@ -975,7 +975,7 @@ obj.grace Readable from: vcl_hit, vcl_deliver The object's grace period in seconds. - + obj.keep @@ -984,7 +984,7 @@ obj.keep Readable from: vcl_hit, vcl_deliver The object's keep period in seconds. - + obj.uncacheable @@ -994,7 +994,7 @@ obj.uncacheable Whether the object is uncacheable (pass, hit-for-pass or hit-for-miss). - + obj.storage @@ -1003,7 +1003,7 @@ obj.storage Readable from: vcl_hit, vcl_deliver The storage backend where this object is stored. - + resp ~~~~ @@ -1060,14 +1060,14 @@ resp.status Writable from: vcl_deliver, vcl_synth The HTTP status code that will be returned. - + Assigning a HTTP standardized code to resp.status will also set resp.reason to the corresponding status message. - + resp.status 200 will get changed into 304 by core code after a return(deliver) from vcl_deliver for conditional requests to cached content if validation succeeds. - + resp.reason @@ -1078,7 +1078,7 @@ resp.reason Writable from: vcl_deliver, vcl_synth The HTTP status message that will be returned. - + resp.http.* @@ -1090,7 +1090,7 @@ resp.http.* Unsetable from: vcl_deliver, vcl_synth - + The HTTP headers that will be returned. resp.do_esi ``VCL >= 4.1`` @@ -1106,7 +1106,7 @@ resp.do_esi ``VCL >= 4.1`` This can be used to selectively disable ESI processing, even though ESI parsing happened during fetch. This is useful when Varnish caches peer with each other. - + resp.is_streaming @@ -1116,7 +1116,7 @@ resp.is_streaming Returns true when the response will be streamed while being fetched from the backend. - + Special variables ~~~~~~~~~~~~~~~~~ @@ -1127,7 +1127,7 @@ now Readable from: all - + The current time, in seconds since the UNIX epoch. When converted to STRING in expressions it returns @@ -1159,10 +1159,10 @@ storage..free_space Readable from: client, backend - + Free space available in the named stevedore. Only available for the malloc stevedore. - + storage..used_space @@ -1170,10 +1170,10 @@ storage..used_space Readable from: client, backend - + Used space in the named stevedore. Only available for the malloc stevedore. - + storage..happy @@ -1181,7 +1181,7 @@ storage..happy Readable from: client, backend - + Health status for the named stevedore. Not available in any of the current stevedores. - + From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:46 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:46 +0000 (UTC) Subject: [6.0] 03fd56af2 Minor FlexeLinting Message-ID: <20180816085246.E2D219B252@lists.varnish-cache.org> commit 03fd56af244e8ba90122900980b703366527fb15 Author: Poul-Henning Kamp Date: Fri Apr 20 10:14:08 2018 +0000 Minor FlexeLinting diff --git a/lib/libvarnish/vus.c b/lib/libvarnish/vus.c index 6315d9533..f233c5f8f 100644 --- a/lib/libvarnish/vus.c +++ b/lib/libvarnish/vus.c @@ -121,7 +121,7 @@ VUS_connect(const char *path, int msec) if (msec != 0) (void)VTCP_nonblocking(s); - i = connect(s, (const struct sockaddr *)&uds, sl); + i = connect(s, (const void*)&uds, sl); if (i == 0) return (s); if (errno != EINPROGRESS) { diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c index 75dda136b..5fa883329 100644 --- a/lib/libvmod_debug/vmod_debug_dyn.c +++ b/lib/libvmod_debug/vmod_debug_dyn.c @@ -262,7 +262,7 @@ xyzzy_dyn_uds__fini(struct xyzzy_debug_dyn_uds **udsp) free(uds->vcl_name); AZ(pthread_mutex_destroy(&uds->mtx)); FREE_OBJ(uds); - udsp = NULL; + *udsp = NULL; } VCL_BACKEND v_matchproto_(td_debug_dyn_uds_backend) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:47 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:47 +0000 (UTC) Subject: [6.0] c45cc5e07 Whitespace OCD Message-ID: <20180816085247.13A249B270@lists.varnish-cache.org> commit c45cc5e07ca4433dbc79dfb6b03905f0dd83bba8 Author: Poul-Henning Kamp Date: Fri Apr 20 10:19:19 2018 +0000 Whitespace OCD diff --git a/lib/libvarnish/vjsn.c b/lib/libvarnish/vjsn.c index d1b34080d..4ba0cd4da 100644 --- a/lib/libvarnish/vjsn.c +++ b/lib/libvarnish/vjsn.c @@ -520,42 +520,41 @@ vjsn_dump(const struct vjsn *js, FILE *fo) * * And run this python in test_parsing: - import glob - - skip = {} - - def emit(fin): - if fin in skip: - return - x = bytearray(open(fin).read()) - if 0 in x: - return - if len(x) > 1000: - return - t = '\t"' - for i in x: - t += "\\x%02x" % i - if len(t) > 64: - print(t + '"') - t = '\t"' - print(t + '",') - - print("const char *good[] = {") - l = list(glob.glob("y_*")) - l.sort() - for f in l: - emit(f) - print("\tNULL") - print("};") - - print("const char *bad[] = {") - l = list(glob.glob("n_*")) - l.sort() - for f in l: - emit(f) - print("\tNULL") - print("};") - + import glob + + skip = {} + + def emit(fin): + if fin in skip: + return + x = bytearray(open(fin).read()) + if 0 in x: + return + if len(x) > 1000: + return + t = '\t"' + for i in x: + t += "\\x%02x" % i + if len(t) > 64: + print(t + '"') + t = '\t"' + print(t + '",') + + print("const char *good[] = {") + l = list(glob.glob("y_*")) + l.sort() + for f in l: + emit(f) + print("\tNULL") + print("};") + + print("const char *bad[] = {") + l = list(glob.glob("n_*")) + l.sort() + for f in l: + emit(f) + print("\tNULL") + print("};") */ static const char *good[] = { From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:47 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:47 +0000 (UTC) Subject: [6.0] 622df9f21 Scope the scope-enum, so it doesn't clash with "VCL" type. Message-ID: <20180816085247.3CD999B299@lists.varnish-cache.org> commit 622df9f219bfef4903feed191e1db12b34dc6a95 Author: Poul-Henning Kamp Date: Fri Apr 20 10:19:46 2018 +0000 Scope the scope-enum, so it doesn't clash with "VCL" type. diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index 168f15a81..1d6877ea3 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -68,10 +68,10 @@ */ enum vmod_directors_shard_param_scope { _SCOPE_INVALID = 0, - VMOD, - VCL, - TASK, - STACK + SCOPE_VMOD, + SCOPE_VCL, + SCOPE_TASK, + SCOPE_STACK }; struct vmod_directors_shard_param; @@ -101,7 +101,7 @@ static const struct vmod_directors_shard_param shard_param_default = { .key = 0, .vcl_name = "builtin defaults", .defaults = NULL, - .scope = VMOD, + .scope = SCOPE_VMOD, .mask = _arg_mask_param, .by = BY_HASH, @@ -747,7 +747,7 @@ vmod_shard_param__init(VRT_CTX, ALLOC_OBJ(p, VMOD_SHARD_SHARD_PARAM_MAGIC); AN(p); p->vcl_name = vcl_name; - p->scope = VCL; + p->scope = SCOPE_VCL; p->defaults = &shard_param_default; *pp = p; @@ -778,7 +778,7 @@ shard_param_stack(struct vmod_directors_shard_param *p, AN(p); INIT_OBJ(p, VMOD_SHARD_SHARD_PARAM_MAGIC); p->vcl_name = who; - p->scope = STACK; + p->scope = SCOPE_STACK; p->defaults = pa; return (p); @@ -808,7 +808,7 @@ shard_param_task(VRT_CTX, const void *id, if (task->priv) { p = task->priv; CHECK_OBJ_NOTNULL(p, VMOD_SHARD_SHARD_PARAM_MAGIC); - assert(p->scope == TASK); + assert(p->scope = SCOPE_TASK); /* XXX VSL(SLT_Debug, 0, "shard_param_task(id %p, pa %p) = %p (found, ws=%p)", @@ -825,9 +825,9 @@ shard_param_task(VRT_CTX, const void *id, task->priv = p; INIT_OBJ(p, VMOD_SHARD_SHARD_PARAM_MAGIC); p->vcl_name = pa->vcl_name; - p->scope = TASK; + p->scope = SCOPE_TASK; - if (id == pa || pa->scope != VCL) + if (id == pa || pa->scope != SCOPE_VCL) p->defaults = pa; else p->defaults = shard_param_task(ctx, pa, pa); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:47 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:47 +0000 (UTC) Subject: [6.0] e54ea1bd1 fix lost workspace overflow markers Message-ID: <20180816085247.6AE489B2C3@lists.varnish-cache.org> commit e54ea1bd1da08fde202996211a30d19bf42010cb Author: Nils Goroll Date: Fri Apr 20 14:10:32 2018 +0200 fix lost workspace overflow markers As WS_Reset() clears the overflow marker, the correct order for resetting and marking an overflow is WS_Reset(); WS_MarkOverflow(); Fixes the last seemingly obscure bit of #2645 diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 86df664b2..76b4c89f9 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -411,8 +411,8 @@ VRT_l_beresp_storage_hint(VRT_CTX, const char *str, ...) if (p == NULL) { VSLb(ctx->vsl, SLT_LostHeader, "storage_hint"); - WS_MarkOverflow(ctx->ws); WS_Reset(ctx->ws, sn); + WS_MarkOverflow(ctx->ws); return; } diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index fdf12276f..865199372 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -154,8 +154,8 @@ vmod_log(VRT_CTX, const char *fmt, ...) va_end(ap); if (p == NULL) { - WS_MarkOverflow(ctx->ws); WS_Reset(ctx->ws, sn); + WS_MarkOverflow(ctx->ws); return; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:47 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:47 +0000 (UTC) Subject: [6.0] 382fc262c Add a fuzzer for the ESI parser Message-ID: <20180816085247.93E259B2E4@lists.varnish-cache.org> commit 382fc262c0a0e1c7fbaa514208678cc3f5ef8dca Author: Federico G. Schwindt Date: Sat Apr 21 08:17:41 2018 +0100 Add a fuzzer for the ESI parser This includes building the fuzzer to avoid code rot, but exercising the fuzzer will be done elsewhere. diff --git a/.gitignore b/.gitignore index 74f73ae61..cdba66f7f 100644 --- a/.gitignore +++ b/.gitignore @@ -130,6 +130,9 @@ cscope.*out /tools/vt_key /tools/vt_key.pub +# fuzzers +/bin/varnishd/esi_parse_fuzzer + # Coverity output /cov-int /myproject.tgz diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 9329f3674..255650181 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -194,6 +194,16 @@ vhp_decode_test_CFLAGS = @SAN_CFLAGS@ \ vhp_decode_test_LDADD = \ $(top_builddir)/lib/libvarnish/libvarnish.a +noinst_PROGRAMS += esi_parse_fuzzer +esi_parse_fuzzer_SOURCES = \ + cache/cache_esi_parse.c \ + fuzzers/esi_parse_fuzzer.c +esi_parse_fuzzer_CFLAGS = \ + @SAN_CFLAGS@ -DNOT_IN_A_VMOD -DTEST_DRIVER -include config.h +esi_parse_fuzzer_LDADD = \ + $(top_builddir)/lib/libvarnish/libvarnish.a \ + $(top_builddir)/lib/libvgz/libvgz.a + TESTS = vhp_table_test vhp_decode_test # diff --git a/bin/varnishd/fuzzers/esi_parse_fuzzer.c b/bin/varnishd/fuzzers/esi_parse_fuzzer.c new file mode 100644 index 000000000..056e63677 --- /dev/null +++ b/bin/varnishd/fuzzers/esi_parse_fuzzer.c @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2018 Varnish Software AS + * All rights reserved. + * + * Author: Federico G. Schwindt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ESI parser fuzzer. + */ + +#include +#include +#include + +#include "cache/cache.h" +#include "cache/cache_vgz.h" /* enum vgz_flag */ +#include "cache/cache_esi.h" +#include "cache/cache_filter.h" /* struct vfp_ctx */ +#include "common/common_param.h" /* struct params */ + +#include "VSC_main.h" +#include "vfil.h" +#include "vsb.h" + +int LLVMFuzzerTestOneInput(const uint8_t *, size_t); + +struct VSC_main *VSC_C_main; +struct params *cache_param; + +void +VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...) +{ + (void)vsl; + (void)tag; + (void)fmt; +} + +void * +WS_Alloc(struct ws *ws, unsigned bytes) +{ + (void)ws; + return (calloc(1, bytes)); +} + +int +LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + struct VSC_main __VSC_C_main; + struct params __cache_param; + struct http req = { .magic = HTTP_MAGIC }; + struct http resp = { .magic = HTTP_MAGIC }; + struct vfp_ctx vc = { .magic = VFP_CTX_MAGIC }; + struct vep_state *vep; + struct vsb *vsb; + struct worker wrk; + txt hd[HTTP_HDR_URL + 1]; + + if (size < 1) + return (0); + + VSC_C_main = &__VSC_C_main; + cache_param = &__cache_param; + + /* Zero out the esi feature bits for now */ + memset(&__cache_param, 0, sizeof(__cache_param)); + + /* Setup req */ + req.hd = hd; + req.hd[HTTP_HDR_URL].b = "/"; + + /* Setup vc */ + vc.wrk = &wrk; + vc.resp = &resp; + + vep = VEP_Init(&vc, &req, NULL, NULL); + AN(vep); + VEP_Parse(vep, (const char *)data, size); + vsb = VEP_Finish(vep); + if (vsb != NULL) + VSB_destroy(&vsb); + free(vep); + + return (0); +} + +#if defined(TEST_DRIVER) +int +main(int argc, char **argv) +{ + size_t len; + char *buf; + int i; + + for (i = 1; i < argc; i++) { + buf = VFIL_readfile(NULL, argv[i], &len); + AN(buf); + LLVMFuzzerTestOneInput(buf, len); + free(buf); + } +} +#endif From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:47 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:47 +0000 (UTC) Subject: [6.0] a9745310b Fix previous Message-ID: <20180816085247.B52489B2FB@lists.varnish-cache.org> commit a9745310b4a9b7f10d94cf9da3ebeb4c117c58ff Author: Federico G. Schwindt Date: Sat Apr 21 08:41:11 2018 +0100 Fix previous diff --git a/bin/varnishd/fuzzers/esi_parse_fuzzer.c b/bin/varnishd/fuzzers/esi_parse_fuzzer.c index 056e63677..0a372b721 100644 --- a/bin/varnishd/fuzzers/esi_parse_fuzzer.c +++ b/bin/varnishd/fuzzers/esi_parse_fuzzer.c @@ -107,14 +107,14 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) int main(int argc, char **argv) { - size_t len; + ssize_t len; char *buf; int i; for (i = 1; i < argc; i++) { buf = VFIL_readfile(NULL, argv[i], &len); AN(buf); - LLVMFuzzerTestOneInput(buf, len); + LLVMFuzzerTestOneInput((uint8_t *)buf, len); free(buf); } } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:47 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:47 +0000 (UTC) Subject: [6.0] 84d38c600 Bump osx image Message-ID: <20180816085247.DBD879B315@lists.varnish-cache.org> commit 84d38c6003dacfc8d17aa2c59057c1860ab7a11b Author: Federico G. Schwindt Date: Sat Apr 21 08:52:22 2018 +0100 Bump osx image diff --git a/.travis.yml b/.travis.yml index 2ff305cec..8a741f6bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ matrix: compiler: clang env: CLANG=6.0 SAN_FLAGS="--enable-asan --enable-ubsan" - os: osx - osx_image: xcode9.2 + osx_image: xcode9.3 compiler: clang allow_failures: - os: osx From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:48 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:48 +0000 (UTC) Subject: [6.0] a4ae1d421 Plug more minor leaks Message-ID: <20180816085248.1F02E9B32D@lists.varnish-cache.org> commit a4ae1d42102e7b0f2e305642e032563f320099f1 Author: Federico G. Schwindt Date: Sun Apr 22 17:07:42 2018 +0100 Plug more minor leaks diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index 8da7c56ef..d814944a2 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -244,7 +244,10 @@ tst_cb(const struct vev *ve, int what) VEV_Stop(vb, jp->evt); free(jp->evt); } - + if (!jp->tst->ntodo) { + free(jp->tst->script); + FREE_OBJ(jp->tst); + } FREE_OBJ(jp); return (1); } diff --git a/tools/lsan.suppr b/tools/lsan.suppr index 89bc6c707..d08ee697c 100644 --- a/tools/lsan.suppr +++ b/tools/lsan.suppr @@ -1,4 +1,6 @@ -leak:varnishtest +# varnishtest +leak:parse_string +leak:receive_frame # pp->{def,min,max} leak:MCF_ParamConf # pp->{def,min,max} From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:48 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:48 +0000 (UTC) Subject: [6.0] f20af5b80 add a noop VSLb_ts to the fuzzer Message-ID: <20180816085248.453229B33D@lists.varnish-cache.org> commit f20af5b80a93c0a72754aa2b1e6abc7b905f9567 Author: Nils Goroll Date: Mon Apr 23 00:55:38 2018 +0200 add a noop VSLb_ts to the fuzzer suncc implements the inline functions from cache.h using it diff --git a/bin/varnishd/fuzzers/esi_parse_fuzzer.c b/bin/varnishd/fuzzers/esi_parse_fuzzer.c index 0a372b721..049d98a6d 100644 --- a/bin/varnishd/fuzzers/esi_parse_fuzzer.c +++ b/bin/varnishd/fuzzers/esi_parse_fuzzer.c @@ -55,6 +55,7 @@ VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...) (void)fmt; } + void * WS_Alloc(struct ws *ws, unsigned bytes) { @@ -62,6 +63,17 @@ WS_Alloc(struct ws *ws, unsigned bytes) return (calloc(1, bytes)); } +void +VSLb_ts(struct vsl_log *l, const char *event, double first, double *pprev, + double now) +{ + (void)l; + (void)event; + (void)first; + (void)pprev; + (void)now; +} + int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:48 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:48 +0000 (UTC) Subject: [6.0] 10303d7d4 Polish Message-ID: <20180816085248.8B14B9B366@lists.varnish-cache.org> commit 10303d7d4935e6da1a933007506f55695fd17d1e Author: Federico G. Schwindt Date: Mon Apr 23 11:10:45 2018 +0100 Polish diff --git a/bin/varnishd/fuzzers/esi_parse_fuzzer.c b/bin/varnishd/fuzzers/esi_parse_fuzzer.c index 049d98a6d..c09c888ba 100644 --- a/bin/varnishd/fuzzers/esi_parse_fuzzer.c +++ b/bin/varnishd/fuzzers/esi_parse_fuzzer.c @@ -55,14 +55,6 @@ VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...) (void)fmt; } - -void * -WS_Alloc(struct ws *ws, unsigned bytes) -{ - (void)ws; - return (calloc(1, bytes)); -} - void VSLb_ts(struct vsl_log *l, const char *event, double first, double *pprev, double now) @@ -74,6 +66,13 @@ VSLb_ts(struct vsl_log *l, const char *event, double first, double *pprev, (void)now; } +void * +WS_Alloc(struct ws *ws, unsigned bytes) +{ + (void)ws; + return (calloc(1, bytes)); +} + int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -90,6 +89,8 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) if (size < 1) return (0); + AN(data); + VSC_C_main = &__VSC_C_main; cache_param = &__cache_param; @@ -124,8 +125,8 @@ main(int argc, char **argv) int i; for (i = 1; i < argc; i++) { + len = 0; buf = VFIL_readfile(NULL, argv[i], &len); - AN(buf); LLVMFuzzerTestOneInput((uint8_t *)buf, len); free(buf); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:48 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:48 +0000 (UTC) Subject: [6.0] 4cd71a88d duh, travis-ci needs to join for this to work Message-ID: <20180816085248.B1C219B371@lists.varnish-cache.org> commit 4cd71a88d222275eabf50dbce21923c247b84792 Author: Federico G. Schwindt Date: Mon Apr 23 13:06:51 2018 +0100 duh, travis-ci needs to join for this to work diff --git a/.travis.yml b/.travis.yml index 8a741f6bc..76a6f705a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,6 @@ notifications: - "irc.linpro.no#varnish-hacking" on_success: change use_notice: true - skip_join: true before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:48 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:48 +0000 (UTC) Subject: [6.0] 6044f91a4 Panic reporting of backend health is a director function Message-ID: <20180816085248.E2DFD9B382@lists.varnish-cache.org> commit 6044f91a4edea271bd90a59b804bba11ddbd56e7 Author: Poul-Henning Kamp Date: Mon Apr 23 20:32:37 2018 +0000 Panic reporting of backend health is a director function diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index acef64826..610132a62 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -413,11 +413,6 @@ vbe_panic(const struct director *d, struct vsb *vsb) VSB_printf(vsb, "ipv6 = %s,\n", bp->ipv6_addr); VSB_printf(vsb, "port = %s,\n", bp->port); VSB_printf(vsb, "hosthdr = %s,\n", bp->hosthdr); - VSB_printf(vsb, "health = %s,\n", - bp->director->health ? "healthy" : "sick"); - VSB_printf(vsb, "admin_health = %s, changed = %f,\n", - VDI_Ahealth(bp->director), - bp->director->health_changed); VSB_printf(vsb, "n_conn = %u,\n", bp->n_conn); } diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c index 30ae7277b..3b6e4b71f 100644 --- a/bin/varnishd/cache/cache_director.c +++ b/bin/varnishd/cache/cache_director.c @@ -244,6 +244,9 @@ VDI_Panic(const struct director *d, struct vsb *vsb, const char *nm) VSB_printf(vsb, "%s = %p {\n", nm, d); VSB_indent(vsb, 2); VSB_printf(vsb, "vcl_name = %s,\n", d->vcl_name); + VSB_printf(vsb, "health = %s,\n", d->health ? "healthy" : "sick"); + VSB_printf(vsb, "admin_health = %s, changed = %f,\n", + VDI_Ahealth(d), d->health_changed); VSB_printf(vsb, "type = %s {\n", d->name); VSB_indent(vsb, 2); if (d->panic != NULL) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:49 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:49 +0000 (UTC) Subject: [6.0] 5300ba5eb Add a VRT_CTX arg to vdir_new(), we will need it Message-ID: <20180816085249.109489B398@lists.varnish-cache.org> commit 5300ba5ebecac233b9c5ccd91e4f1c46d92f9b2d Author: Poul-Henning Kamp Date: Mon Apr 23 21:27:57 2018 +0000 Add a VRT_CTX arg to vdir_new(), we will need it diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c index 202431e9b..8ae3ddc30 100644 --- a/lib/libvmod_directors/fall_back.c +++ b/lib/libvmod_directors/fall_back.c @@ -98,7 +98,7 @@ vmod_fallback__init(VRT_CTX, ALLOC_OBJ(fb, VMOD_DIRECTORS_FALLBACK_MAGIC); AN(fb); *fbp = fb; - vdir_new(&fb->vd, "fallback", vcl_name, vmod_fallback_healthy, + vdir_new(ctx, &fb->vd, "fallback", vcl_name, vmod_fallback_healthy, vmod_fallback_resolve, fb); fb->st = sticky; } diff --git a/lib/libvmod_directors/hash.c b/lib/libvmod_directors/hash.c index 80a792e97..a05308195 100644 --- a/lib/libvmod_directors/hash.c +++ b/lib/libvmod_directors/hash.c @@ -59,7 +59,7 @@ vmod_hash__init(VRT_CTX, struct vmod_directors_hash **rrp, ALLOC_OBJ(rr, VMOD_DIRECTORS_HASH_MAGIC); AN(rr); *rrp = rr; - vdir_new(&rr->vd, "hash", vcl_name, NULL, NULL, rr); + vdir_new(ctx, &rr->vd, "hash", vcl_name, NULL, NULL, rr); } VCL_VOID v_matchproto_() diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c index 91fb3ce08..4ce6328f3 100644 --- a/lib/libvmod_directors/random.c +++ b/lib/libvmod_directors/random.c @@ -86,7 +86,7 @@ vmod_random__init(VRT_CTX, struct vmod_directors_random **rrp, ALLOC_OBJ(rr, VMOD_DIRECTORS_RANDOM_MAGIC); AN(rr); *rrp = rr; - vdir_new(&rr->vd, "random", vcl_name, vmod_random_healthy, + vdir_new(ctx, &rr->vd, "random", vcl_name, vmod_random_healthy, vmod_random_resolve, rr); } diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c index 3c896cbba..7e888f365 100644 --- a/lib/libvmod_directors/round_robin.c +++ b/lib/libvmod_directors/round_robin.c @@ -95,7 +95,7 @@ vmod_round_robin__init(VRT_CTX, ALLOC_OBJ(rr, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC); AN(rr); *rrp = rr; - vdir_new(&rr->vd, "round-robin", vcl_name, vmod_rr_healthy, + vdir_new(ctx, &rr->vd, "round-robin", vcl_name, vmod_rr_healthy, vmod_rr_resolve, rr); } diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c index 6a06412d2..95cc9dfa4 100644 --- a/lib/libvmod_directors/vdir.c +++ b/lib/libvmod_directors/vdir.c @@ -50,11 +50,12 @@ vdir_expand(struct vdir *vd, unsigned n) } void -vdir_new(struct vdir **vdp, const char *name, const char *vcl_name, +vdir_new(VRT_CTX, struct vdir **vdp, const char *name, const char *vcl_name, vdi_healthy_f *healthy, vdi_resolve_f *resolve, void *priv) { struct vdir *vd; + AN(ctx); AN(name); AN(vcl_name); AN(vdp); diff --git a/lib/libvmod_directors/vdir.h b/lib/libvmod_directors/vdir.h index c4862e580..afdc42177 100644 --- a/lib/libvmod_directors/vdir.h +++ b/lib/libvmod_directors/vdir.h @@ -41,7 +41,8 @@ struct vdir { struct vbitmap *vbm; }; -void vdir_new(struct vdir **vdp, const char *name, const char *vcl_name, +void vdir_new(VRT_CTX, struct vdir **vdp, const char *name, + const char *vcl_name, vdi_healthy_f *healthy, vdi_resolve_f *resolve, void *priv); void vdir_delete(struct vdir **vdp); void vdir_rdlock(struct vdir *vd); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:49 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:49 +0000 (UTC) Subject: [6.0] c0e25e6a5 Complement VDP error handling Message-ID: <20180816085249.425119B3A9@lists.varnish-cache.org> commit c0e25e6a5cb3635e4bd08d0c17cc095ea643ced6 Author: Nils Goroll Date: Mon Apr 23 11:25:57 2018 +0200 Complement VDP error handling * remember push errors in the context * also fail additional pushes once we saw an error Try to fail requests as early as possible. Otherwise just calling VDP functions after an error is a noop. Fixes #2618 diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c index 20439b140..e3cdcee5c 100644 --- a/bin/varnishd/cache/cache_deliver_proc.c +++ b/bin/varnishd/cache/cache_deliver_proc.c @@ -73,7 +73,7 @@ VDP_bytes(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) return (vdc->retval); } -void +int VDP_push(struct req *req, const struct vdp *vdp, void *priv, int bottom) { struct vdp_entry *vdpe; @@ -85,12 +85,18 @@ VDP_push(struct req *req, const struct vdp *vdp, void *priv, int bottom) AN(vdp->name); AN(vdp->func); + if (vdc->retval) + return (vdc->retval); + if (DO_DEBUG(DBG_PROCESSORS)) VSLb(req->vsl, SLT_Debug, "VDP_push(%s)", vdp->name); vdpe = WS_Alloc(req->ws, sizeof *vdpe); - if (vdpe == NULL) - return; + if (vdpe == NULL) { + AZ(vdc->retval); + vdc->retval = -1; + return (vdc->retval); + } INIT_OBJ(vdpe, VDP_ENTRY_MAGIC); vdpe->vdp = vdp; vdpe->priv = priv; @@ -100,7 +106,9 @@ VDP_push(struct req *req, const struct vdp *vdp, void *priv, int bottom) VTAILQ_INSERT_HEAD(&vdc->vdp, vdpe, list); vdc->nxt = VTAILQ_FIRST(&vdc->vdp); - AZ(vdpe->vdp->func(req, VDP_INIT, &vdpe->priv, NULL, 0)); + AZ(vdc->retval); + vdc->retval = vdpe->vdp->func(req, VDP_INIT, &vdpe->priv, NULL, 0); + return (vdc->retval); } void @@ -113,10 +121,15 @@ VDP_close(struct req *req) vdc = req->vdc; while (!VTAILQ_EMPTY(&vdc->vdp)) { vdpe = VTAILQ_FIRST(&vdc->vdp); - CHECK_OBJ_NOTNULL(vdpe, VDP_ENTRY_MAGIC); - VTAILQ_REMOVE(&vdc->vdp, vdpe, list); - AZ(vdpe->vdp->func(req, VDP_FINI, &vdpe->priv, NULL, 0)); - AZ(vdpe->priv); + if (vdc->retval >= 0) + AN(vdpe); + if (vdpe != NULL) { + CHECK_OBJ_NOTNULL(vdpe, VDP_ENTRY_MAGIC); + VTAILQ_REMOVE(&vdc->vdp, vdpe, list); + AZ(vdpe->vdp->func(req, VDP_FINI, &vdpe->priv, + NULL, 0)); + AZ(vdpe->priv); + } vdc->nxt = VTAILQ_FIRST(&vdc->vdp); } } diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 3af698593..1829804d6 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -815,9 +815,9 @@ ved_deliver(struct req *req, struct boc *boc, int wantbody) ved_stripgzip(req, boc); } else { if (ecx->isgzip && !i) - VDP_push(req, &ved_vdp_pgz, ecx, 1); + (void)VDP_push(req, &ved_vdp_pgz, ecx, 1); else - VDP_push(req, &ved_ved, ecx->preq, 1); + (void)VDP_push(req, &ved_ved, ecx->preq, 1); (void)VDP_DeliverObj(req); (void)VDP_bytes(req, VDP_FLUSH, NULL, 0); } diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h index f6dae16e9..0bf90732d 100644 --- a/bin/varnishd/cache/cache_filter.h +++ b/bin/varnishd/cache/cache_filter.h @@ -121,8 +121,8 @@ struct vdp_ctx { #define VDP_CTX_MAGIC 0xee501df7 struct vdp_entry_s vdp; struct vdp_entry *nxt; - unsigned retval; + int retval; }; int VDP_bytes(struct req *, enum vdp_action act, const void *ptr, ssize_t len); -void VDP_push(struct req *, const struct vdp *, void *priv, int bottom); +int VDP_push(struct req *, const struct vdp *, void *priv, int bottom); diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c index acd7034ae..373d1f676 100644 --- a/bin/varnishd/cache/cache_range.c +++ b/bin/varnishd/cache/cache_range.c @@ -175,7 +175,8 @@ vrg_dorange(struct req *req, const char *r) vrg_priv->range_off = 0; vrg_priv->range_low = low; vrg_priv->range_high = high + 1; - VDP_push(req, &vrg_vdp, vrg_priv, 1); + if (VDP_push(req, &vrg_vdp, vrg_priv, 1)) + return ("WS too small"); http_PutResponse(req->resp, "HTTP/1.1", 206, NULL); return (NULL); } diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index e327c0d53..00a02491b 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -342,7 +342,7 @@ cnt_transmit(struct worker *wrk, struct req *req) struct boc *boc; const char *r; uint16_t status; - int sendbody; + int err, sendbody; intmax_t clval; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -375,15 +375,18 @@ cnt_transmit(struct worker *wrk, struct req *req) } else sendbody = 1; + err = 0; if (sendbody >= 0) { if (!req->disable_esi && req->resp_len != 0 && - ObjHasAttr(wrk, req->objcore, OA_ESIDATA)) - VDP_push(req, &VDP_esi, NULL, 0); + ObjHasAttr(wrk, req->objcore, OA_ESIDATA) && + VDP_push(req, &VDP_esi, NULL, 0) < 0) + err++; if (cache_param->http_gzip_support && ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) && - !RFC2616_Req_Gzip(req->http)) - VDP_push(req, &VDP_gunzip, NULL, 1); + !RFC2616_Req_Gzip(req->http) && + VDP_push(req, &VDP_gunzip, NULL, 1) < 0) + err++; if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) { @@ -405,7 +408,12 @@ cnt_transmit(struct worker *wrk, struct req *req) "Content-Length: %jd", req->resp_len); } - req->transport->deliver(req, boc, sendbody); + if (err == 0) + req->transport->deliver(req, boc, sendbody); + else { + VSLb(req->vsl, SLT_Error, "Failure to push processors"); + req->doclose = SC_OVERLOAD; + } VSLb_ts_req(req, "Resp", W_TIM_real(wrk)); diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index c7a622691..fda38dda4 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -128,8 +128,11 @@ V1D_Deliver(struct req *req, struct boc *boc, int sendbody) if (req->resp_len == 0) sendbody = 0; - if (sendbody) - VDP_push(req, &v1d_vdp, NULL, 1); + if (sendbody && VDP_push(req, &v1d_vdp, NULL, 1)) { + v1d_error(req, "workspace_thread overflow"); + AZ(req->wrk->v1l); + return; + } AZ(req->wrk->v1l); V1L_Open(req->wrk, req->wrk->aws, diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c index a9f43e9b0..a0ff969e6 100644 --- a/bin/varnishd/http2/cache_http2_deliver.c +++ b/bin/varnishd/http2/cache_http2_deliver.c @@ -265,10 +265,13 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) WS_Release(req->ws, 0); - if (sendbody) { - VDP_push(req, &h2_vdp, NULL, 1); + /* XXX someone into H2 please add appropriate error handling */ + while (sendbody) { + err = VDP_push(req, &h2_vdp, NULL, 1); + if (err) + break; err = VDP_DeliverObj(req); - /*XXX*/(void)err; + break; } AZ(req->wrk->v1l); diff --git a/bin/varnishtest/tests/r02618.vtc b/bin/varnishtest/tests/r02618.vtc new file mode 100644 index 000000000..efe1a23c6 --- /dev/null +++ b/bin/varnishtest/tests/r02618.vtc @@ -0,0 +1,25 @@ +varnishtest "sweep through tight client workspace conditions in deliver" + +server s1 { + rxreq + txresp -hdr "Cache-Control: mag-age=3600" -bodylen 1024 +} -start + +varnish v1 -vcl+backend { + import vtc; + import std; + sub vcl_recv { + return (hash); + } + sub vcl_deliver { + vtc.workspace_alloc(client, -4 * + (std.integer(req.xid, 1001) - 1001) / 2); + } +} -start + +client c1 -repeat 100 { + txreq -url "/" + # some responses will fail (503), some won't. All we care + # about here is the fact that we don't panic + rxresp +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:49 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:49 +0000 (UTC) Subject: [6.0] d023c39c0 add git Message-ID: <20180816085249.7B7BE9B3D2@lists.varnish-cache.org> commit d023c39c0133cba35d95e545adcd37c872e4a4cd Author: Nils Goroll Date: Tue Apr 24 12:06:04 2018 +0200 add git diff --git a/doc/sphinx/installation/install.rst b/doc/sphinx/installation/install.rst index 101db8ea0..896d29c65 100644 --- a/doc/sphinx/installation/install.rst +++ b/doc/sphinx/installation/install.rst @@ -100,6 +100,10 @@ Recommended, in particular if you plan on building custom vmods:: sudo apt-get install autoconf-archive +Optionally, to pull from a repository:: + + sudo apt-get install git + Build dependencies on Red Hat / CentOS -------------------------------------- @@ -125,6 +129,10 @@ Optionally, to rebuild the svg files:: yum install graphviz +Optionally, to pull from a repository:: + + yum install git + .. XXX autoconf-archive ? is this any helpful on the notoriously outdated Redhats? From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:49 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:49 +0000 (UTC) Subject: [6.0] f7831b621 Upgrade brew's Python to avoid linking errors Message-ID: <20180816085249.A08FA9B3E5@lists.varnish-cache.org> commit f7831b62113e754d96c08b1ddd1be2a43a10a005 Author: Carla Date: Wed Apr 25 12:35:55 2018 +0200 Upgrade brew's Python to avoid linking errors See: https://github.com/Homebrew/homebrew-core/issues/26358 diff --git a/.travis.yml b/.travis.yml index 76a6f705a..2a8408884 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,7 @@ notifications: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; + brew upgrade python; brew install docutils sphinx-doc nghttp2; fi - if [[ -n "$CLANG" ]]; then From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:50 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:50 +0000 (UTC) Subject: [6.0] 50dcc8b3b Ensure sphinx is in the PATH Message-ID: <20180816085250.4657C9B422@lists.varnish-cache.org> commit 50dcc8b3b0d043739c47d2533bde752543581afa Author: Federico G. Schwindt Date: Thu Apr 26 10:25:09 2018 +0100 Ensure sphinx is in the PATH diff --git a/.travis.yml b/.travis.yml index 2a8408884..2cae8dbee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,6 +58,7 @@ before_install: - ./configure ${CONFIGURE_ARGS} script: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - export PYTHONPATH=`brew --prefix`/lib/python2.7/site-packages; fi + export PYTHONPATH=`brew --prefix`/lib/python2.7/site-packages; + export PATH="/usr/local/opt/sphinx-doc/bin:$PATH"; fi - if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then make -j3 distcheck; fi - if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then make -j3 check VERBOSE=1; fi From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:50 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:50 +0000 (UTC) Subject: [6.0] 23ab35c25 On startup, tell what varnish version this is Message-ID: <20180816085250.72AA99B432@lists.varnish-cache.org> commit 23ab35c25f3d7be97d8a386e6fb4ccc5d9ad3ca2 Author: Federico G. Schwindt Date: Thu Apr 26 10:25:26 2018 +0100 On startup, tell what varnish version this is Fixes #2661. diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index 237a45bd0..cad50a499 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -842,6 +842,7 @@ main(int argc, char * const *argv) assert(!VPF_Write(pfh1)); assert(pfh2 == NULL || !VPF_Write(pfh2)); + MGT_Complain(C_DEBUG, "Version: %s", VCS_version); MGT_Complain(C_DEBUG, "Platform: %s", VSB_data(vident) + 1); if (d_flag) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:50 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:50 +0000 (UTC) Subject: [6.0] 0c8ffd99e Include header to support musl Message-ID: <20180816085250.ACD859B440@lists.varnish-cache.org> commit 0c8ffd99ed91bc858ab8c50e2955f1dcb85ecdb3 Author: Guillaume Quintard Date: Thu Apr 26 21:50:38 2018 +0200 Include header to support musl diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 35dd2e898..88162a951 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -33,6 +33,7 @@ #include #include #include +#include /* for MUSL (mode_t) */ #include #include "vtc.h" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:50 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:50 +0000 (UTC) Subject: [6.0] 6b27d7aa1 Tell which director the NULL backend was attempted on Message-ID: <20180816085250.D16139B451@lists.varnish-cache.org> commit 6b27d7aa146d7137eda70206d8de89d2b1a84a5c Author: Poul-Henning Kamp Date: Thu Apr 26 21:15:30 2018 +0000 Tell which director the NULL backend was attempted on diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c index 95cc9dfa4..84895c365 100644 --- a/lib/libvmod_directors/vdir.c +++ b/lib/libvmod_directors/vdir.c @@ -122,7 +122,8 @@ vdir_add_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, double weight) CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) { - VRT_fail(ctx, "NULL backend cannot be added"); + VRT_fail(ctx, "%s: NULL backend cannot be added", + vd->dir->vcl_name); return; } AN(be); @@ -144,7 +145,8 @@ vdir_remove_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, unsigned *cur) CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) { - VRT_fail(ctx, "NULL backend cannot be removed"); + VRT_fail(ctx, "%s: NULL backend cannot be removed", + vd->dir->vcl_name); return; } CHECK_OBJ(be, DIRECTOR_MAGIC); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:50 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:50 +0000 (UTC) Subject: [6.0] aa797877e Fix compiling under epel6 Message-ID: <20180816085250.F3E7C9B46D@lists.varnish-cache.org> commit aa797877e7d9feaf584ab56a57a6e96350dabb09 Author: Federico G. Schwindt Date: Fri Apr 27 00:07:14 2018 +0100 Fix compiling under epel6 Reported by ingvar diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 7ab093b90..5e3816bca 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -485,7 +485,7 @@ process_stdout(const struct vev *ev, int what) vtc_dump(p->vl, 4, "stdout", buf, i); else if (p->log == 3) vtc_hexdump(p->vl, 4, "stdout", buf, i); - (void)write(p->f_stdout, buf, i); + assert(write(p->f_stdout, buf, i) == i); AZ(pthread_mutex_lock(&p->mtx)); teken_input(p->tek, buf, i); AZ(pthread_mutex_unlock(&p->mtx)); @@ -510,7 +510,7 @@ process_stderr(const struct vev *ev, int what) p->stderr_bytes += i; AZ(pthread_mutex_unlock(&p->mtx)); vtc_dump(p->vl, 4, "stderr", buf, i); - (void)write(p->f_stderr, buf, i); + assert(write(p->f_stderr, buf, i) == i); return (0); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:51 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:51 +0000 (UTC) Subject: [6.0] 93909642c vmodtool: require method names to start with a dot Message-ID: <20180816085251.211249B488@lists.varnish-cache.org> commit 93909642c813063a22ae8cdd9be687f0cd08cb98 Author: Nils Goroll Date: Fri Apr 27 16:39:06 2018 +0200 vmodtool: require method names to start with a dot diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index b6495c5b8..b4de6a036 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -799,6 +799,9 @@ class s_method(stanza): assert type(p) == s_object self.pfx = p.proto.name self.proto = prototype(self, prefix=self.pfx) + if not self.proto.bname.startswith("."): + err("$Method %s: Method names need to start with . (dot)" + % self.proto.bname, warn=False) self.proto.obj = "x" + self.pfx self.rstlbl = "func_" + self.proto.name p.methods.append(self) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:51 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:51 +0000 (UTC) Subject: [6.0] 988baa400 vmodtool: fix object destructor signature Message-ID: <20180816085251.443B39B49E@lists.varnish-cache.org> commit 988baa400e954ccfd3c2a2304e89ee3affd24004 Author: Nils Goroll Date: Fri Apr 27 16:58:01 2018 +0200 vmodtool: fix object destructor signature ... when the constructor has optional arguments diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index b4de6a036..8937aefac 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -719,6 +719,7 @@ class s_object(stanza): self.fini = copy.copy(self.proto) self.fini.name += '__fini' + self.fini.argstruct = False self.fini.args = [] self.rstlbl = "obj_" + self.proto.name From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:51 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:51 +0000 (UTC) Subject: [6.0] 2fe5d09e4 Fix gensequences for BusyBox awk Message-ID: <20180816085251.66A939B4A8@lists.varnish-cache.org> commit 2fe5d09e412081199be6d1d106c4056806959d87 Author: Guillaume Quintard Date: Thu Apr 26 21:59:41 2018 +0200 Fix gensequences for BusyBox awk I never thought that I'd have to fix a string concatenation problem in a BusyBox awk program to generate VT100 code in a container, but here we are: echo | awk 'END {print "foo" "" ++a, "foo" ++a}' should output "foo0 foo1", and for all the ?awk I tested, it does, except for BusyBox awk who thought funny to output "0 foo1", breaking the teken_state.h file. diff --git a/bin/varnishtest/gensequences b/bin/varnishtest/gensequences index 83a3d1089..8c2299a61 100644 --- a/bin/varnishtest/gensequences +++ b/bin/varnishtest/gensequences @@ -61,7 +61,7 @@ while (getline > 0) { l_prefix_parent[n] = prefix; l_prefix_suffix[n] = sequence[i]; if (!l_prefix_name[n]) - l_prefix_name[n] = "teken_state_" ++npr; + l_prefix_name[n] = "teken_state_" "" ++npr; prefix = n; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:51 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:51 +0000 (UTC) Subject: [6.0] f36f80a0c Make a00009.vtc pass on alpine Message-ID: <20180816085251.8961B9B4BB@lists.varnish-cache.org> commit f36f80a0cdc1b563f2d755203042eef8140da779 Author: Guillaume Quintard Date: Thu Apr 26 23:43:59 2018 +0200 Make a00009.vtc pass on alpine alpine's getopt returns "progname: unrecognized option: A" diff --git a/bin/varnishtest/tests/a00009.vtc b/bin/varnishtest/tests/a00009.vtc index 37565c796..4b82d4c7d 100644 --- a/bin/varnishtest/tests/a00009.vtc +++ b/bin/varnishtest/tests/a00009.vtc @@ -13,7 +13,7 @@ shell -err -expect {Too many arguments for -x} "varnishd -x foo bar" shell -err -expect {Invalid -x argument} "varnishd -x foo " # This one is tricky, the getopt message on stderr is not standardized. -shell -err -expect {option --} "varnishd -A " +shell -err -expect {option} "varnishd -A " shell -err -expect {Usage: varnishd [options]} "varnishd -? " shell -err -expect {Too many arguments} "varnishd foo " From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:51 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:51 +0000 (UTC) Subject: [6.0] d5e88cf73 Stabilize this test Message-ID: <20180816085251.AC4849B4CD@lists.varnish-cache.org> commit d5e88cf733720f6fa3ef07643a9a982a5b70631d Author: Poul-Henning Kamp Date: Mon Apr 30 09:29:24 2018 +0000 Stabilize this test diff --git a/bin/varnishtest/tests/u00010.vtc b/bin/varnishtest/tests/u00010.vtc index fc555ff8a..5813db981 100644 --- a/bin/varnishtest/tests/u00010.vtc +++ b/bin/varnishtest/tests/u00010.vtc @@ -2,7 +2,7 @@ varnishtest "trivial run of varnishtop in curses mode" server s1 { rxreq - txresp + txresp -hdr "Connection: close" } -start varnish v1 -vcl+backend {} -start From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:51 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:51 +0000 (UTC) Subject: [6.0] 6b2e8ec0b document a potential race Message-ID: <20180816085251.D0C189B4E0@lists.varnish-cache.org> commit 6b2e8ec0b6556c1d150499d528e57c168cfd0db3 Author: Nils Goroll Date: Mon Apr 30 13:48:16 2018 +0200 document a potential race closes #2625 diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c index 86777ae6c..fd416e822 100644 --- a/bin/varnishd/cache/cache_tcp_pool.c +++ b/bin/varnishd/cache/cache_tcp_pool.c @@ -667,6 +667,10 @@ VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6, const char *uds, if (cp != NULL) return (cp->priv); + /* + * this is racy - we could end up with additional pools on the same id / + * destination address with just a single connection + */ ALLOC_OBJ(tp, TCP_POOL_MAGIC); AN(tp); if (uds != NULL) { From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:50 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:50 +0000 (UTC) Subject: [6.0] 86326f95b Make sure daemonized haproxy processes gets killed Message-ID: <20180816085250.21A199B416@lists.varnish-cache.org> commit 86326f95bf598b180715e9e3e098e916b344a2a3 Author: Poul-Henning Kamp Date: Thu Apr 26 08:29:21 2018 +0000 Make sure daemonized haproxy processes gets killed diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 8d4118fe5..35dd2e898 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -327,15 +327,16 @@ haproxy_wait(struct haproxy *h) sig = SIGINT; n = 0; vtc_log(h->vl, 2, "Stop HAproxy pid=%ld", (long)h->pid); - while (!h->opt_check_mode && !h->its_dead_jim) { + while (h->opt_daemon || (!h->opt_check_mode && !h->its_dead_jim)) { assert(h->pid > 0); if (n == 0) { - i= kill(h->pid, sig); - vtc_log(h->vl, 4, - "Kill(%d)=%d: %s", sig, i, strerror(errno)); - h->expect_signal = -sig; + i = kill(h->pid, sig); + if (i == 0) + h->expect_signal = -sig; if (i && errno == ESRCH) break; + vtc_log(h->vl, 4, + "Kill(%d)=%d: %s", sig, i, strerror(errno)); } usleep(100000); if (++n == 20) { From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] 02e1771be Symbolic status for HTC FetchError Message-ID: <20180816085252.087679B4FB@lists.varnish-cache.org> commit 02e1771be8cf3c18be3f9752ebb8edaae4b0a02d Author: Nils Goroll Date: Wed Feb 21 14:21:19 2018 +0100 Symbolic status for HTC FetchError Merges #2577 diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 3e96b7864..a6c8f8378 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -182,6 +182,21 @@ SES_Get_String_Attr(const struct sess *sp, enum sess_attr a) /*--------------------------------------------------------------------*/ +const char * +HTC_Status(enum htc_status_e e) +{ + switch (e) { +#define HTC_STATUS(e, n, s, l) \ + case HTC_S_ ## e: return (s); +#include "tbl/htc.h" + default: + WRONG("HTC_Status"); + } + NEEDLESS(return (NULL)); +} + +/*--------------------------------------------------------------------*/ + void HTC_RxInit(struct http_conn *htc, struct ws *ws) { diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index e05e87c4c..9283ba433 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -342,6 +342,7 @@ void SES_Ref(struct sess *sp); void SES_Rel(struct sess *sp); int SES_Reschedule_Req(struct req *, enum task_prio); +const char * HTC_Status(enum htc_status_e); void HTC_RxInit(struct http_conn *htc, struct ws *ws); void HTC_RxPipeline(struct http_conn *htc, void *); enum htc_status_e HTC_RxStuff(struct http_conn *, htc_complete_f *, @@ -355,15 +356,8 @@ void SES_Set_String_Attr(struct sess *sp, enum sess_attr a, const char *src); enum htc_status_e { - HTC_S_JUNK = -5, - HTC_S_CLOSE = -4, - HTC_S_TIMEOUT = -3, - HTC_S_OVERFLOW = -2, - HTC_S_EOF = -1, - HTC_S_EMPTY = 0, - HTC_S_MORE = 1, - HTC_S_COMPLETE = 2, - HTC_S_IDLE = 3, +#define HTC_STATUS(e, n, s, l) HTC_S_ ## e = n, +#include "tbl/htc.h" }; /* cache_shmlog.c */ diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 27bf52101..2ddc58142 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -192,7 +192,8 @@ V1F_FetchRespHdr(struct busyobj *bo) htc->doclose = SC_RX_OVERFLOW; break; default: - VSLb(bo->vsl, SLT_FetchError, "HTC status %d", hs); + VSLb(bo->vsl, SLT_FetchError, "HTC %s (%d)", + HTC_Status(hs), hs); htc->doclose = SC_RX_BAD; break; } diff --git a/include/Makefile.am b/include/Makefile.am index d0d88c97d..3a6bb822c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -98,7 +98,8 @@ nobase_noinst_HEADERS = \ vss.h \ vtcp.h \ vtree.h \ - vus.h + vus.h \ + tbl/htc.h ## keep in sync with lib/libvcc/Makefile.am vcl.h: \ diff --git a/include/tbl/htc.h b/include/tbl/htc.h new file mode 100644 index 000000000..a46b75e28 --- /dev/null +++ b/include/tbl/htc.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2006 Verdens Gang AS + * Copyright (c) 2006-2015 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * HTC status values + */ + +/*lint -save -e525 -e539 */ + +// enum htc_status_e n short long +HTC_STATUS(JUNK, -5, "junk", "Received unexpected data") +HTC_STATUS(CLOSE, -4, "close", "Connection closed") // unused? +HTC_STATUS(TIMEOUT, -3, "timeout", "Timed out") +HTC_STATUS(OVERFLOW, -2, "overflow", "Buffer too small") +HTC_STATUS(EOF, -1, "eof", "EOF received") +HTC_STATUS(EMPTY, 0, "empty", "Empty response") +HTC_STATUS(MORE, 1, "more", "More data required") +HTC_STATUS(COMPLETE, 2, "complete", "Data complete") +HTC_STATUS(IDLE, 3, "idle", "Return to waiter") +#undef HTC_STATUS +/*lint -restore */ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] b0371af3e Make two functions to get from req/bo to VRT_CTX Message-ID: <20180816085252.2C1DF9B51A@lists.varnish-cache.org> commit b0371af3e53ae4a60555164286cd3c9c2a1763cf Author: Poul-Henning Kamp Date: Tue May 1 07:37:27 2018 +0000 Make two functions to get from req/bo to VRT_CTX Conflicts: bin/varnishd/cache/cache_director.c diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 9283ba433..111c6530f 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -388,6 +388,9 @@ void VCL_Refresh(struct vcl **); void VCL_Rel(struct vcl **); const char *VCL_Return_Name(unsigned); const char *VCL_Method_Name(unsigned); +void VCL_Bo2Ctx(struct vrt_ctx *, struct busyobj *); +void VCL_Req2Ctx(struct vrt_ctx *, struct req *); + #define VCL_MET_MAC(l,u,t,b) \ void VCL_##l##_method(struct vcl *, struct worker *, struct req *, \ struct busyobj *bo, void *specific); diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index abc519f39..98cc47dec 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -69,6 +69,42 @@ static uintptr_t ws_snapshot_cli; /*--------------------------------------------------------------------*/ +void +VCL_Bo2Ctx(struct vrt_ctx *ctx, struct busyobj *bo) +{ + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); + ctx->vcl = bo->vcl; + ctx->vsl = bo->vsl; + ctx->http_bereq = bo->bereq; + ctx->http_beresp = bo->beresp; + ctx->bo = bo; + ctx->sp = bo->sp; + ctx->now = bo->t_prev; + ctx->ws = bo->ws; +} + +void +VCL_Req2Ctx(struct vrt_ctx *ctx, struct req *req) +{ + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + ctx->vcl = req->vcl; + ctx->vsl = req->vsl; + ctx->http_req = req->http; + ctx->http_req_top = req->top->http; + ctx->http_resp = req->resp; + ctx->req = req; + ctx->sp = req->sp; + ctx->now = req->t_prev; + ctx->ws = req->ws; +} + +/*--------------------------------------------------------------------*/ + static struct vrt_ctx * vcl_get_ctx(unsigned method, int msg) { diff --git a/bin/varnishd/cache/cache_vcl_vrt.c b/bin/varnishd/cache/cache_vcl_vrt.c index 484c14b4a..f040f9027 100644 --- a/bin/varnishd/cache/cache_vcl_vrt.c +++ b/bin/varnishd/cache/cache_vcl_vrt.c @@ -340,7 +340,6 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, void *specific, unsigned method, vcl_func_f *func) { uintptr_t aws; - struct vsl_log *vsl = NULL; struct vrt_ctx ctx; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -349,33 +348,17 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(req->vcl, VCL_MAGIC); - vsl = req->vsl; - ctx.vcl = req->vcl; - ctx.http_req = req->http; - ctx.http_req_top = req->top->http; - ctx.http_resp = req->resp; - ctx.req = req; - ctx.sp = req->sp; - ctx.now = req->t_prev; - ctx.ws = req->ws; + VCL_Req2Ctx(&ctx, req); } if (bo != NULL) { if (req) assert(method == VCL_MET_PIPE); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo->vcl, VCL_MAGIC); - vsl = bo->vsl; - ctx.vcl = bo->vcl; - ctx.http_bereq = bo->bereq; - ctx.http_beresp = bo->beresp; - ctx.bo = bo; - ctx.sp = bo->sp; - ctx.now = bo->t_prev; - ctx.ws = bo->ws; + VCL_Bo2Ctx(&ctx, bo); } assert(ctx.now != 0); ctx.syntax = ctx.vcl->conf->syntax; - ctx.vsl = vsl; ctx.specific = specific; ctx.method = method; wrk->handling = 0; @@ -383,10 +366,10 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo, aws = WS_Snapshot(wrk->aws); wrk->cur_method = method; wrk->seen_methods |= method; - AN(vsl); - VSLb(vsl, SLT_VCL_call, "%s", VCL_Method_Name(method)); + AN(ctx.vsl); + VSLb(ctx.vsl, SLT_VCL_call, "%s", VCL_Method_Name(method)); func(&ctx); - VSLb(vsl, SLT_VCL_return, "%s", VCL_Return_Name(wrk->handling)); + VSLb(ctx.vsl, SLT_VCL_return, "%s", VCL_Return_Name(wrk->handling)); wrk->cur_method |= 1; // Magic marker if (wrk->handling == VCL_RET_FAIL) wrk->stats->vcl_fail++; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] 6a7a21226 Print usage on unknown or missing arguments Message-ID: <20180816085252.5182F9B526@lists.varnish-cache.org> commit 6a7a212262097379c02750633a3cc96e8967ed86 Author: Federico G. Schwindt Date: Mon Apr 30 21:13:23 2018 +0100 Print usage on unknown or missing arguments This seems to be the de-facto way to handle such cases. Fixes #2608. diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c index cad50a499..aada3ce2c 100644 --- a/bin/varnishd/mgt/mgt_main.c +++ b/bin/varnishd/mgt/mgt_main.c @@ -488,8 +488,7 @@ main(int argc, char * const *argv) do { switch (o) { case '?': - if (optopt == '?') - usage(); + usage(); exit(2); case 'V': case 'x': From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] e6b07a3e1 move tbl/htc.h to installed headers Message-ID: <20180816085252.73D119B539@lists.varnish-cache.org> commit e6b07a3e13cb23bfafca1f716cca4216ddd591ea Author: Nils Goroll Date: Tue May 1 18:35:11 2018 +0200 move tbl/htc.h to installed headers consequence of 90c4b747ced9053353c13d827ef0a0df5ab4445f: if cache_varnishd.h is installed, we also need table files used therein. diff --git a/include/Makefile.am b/include/Makefile.am index 3a6bb822c..27f40ec86 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,6 +16,7 @@ nobase_pkginclude_HEADERS = \ tbl/h2_frames.h \ tbl/h2_settings.h \ tbl/h2_stream.h \ + tbl/htc.h \ tbl/http_headers.h \ tbl/http_response.h \ tbl/locks.h \ @@ -98,8 +99,7 @@ nobase_noinst_HEADERS = \ vss.h \ vtcp.h \ vtree.h \ - vus.h \ - tbl/htc.h + vus.h ## keep in sync with lib/libvcc/Makefile.am vcl.h: \ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] 36dff5b48 avoid interactive mv Message-ID: <20180816085252.945E29B54D@lists.varnish-cache.org> commit 36dff5b4807b1525ec30b76697d2380c44610688 Author: Nils Goroll Date: Tue May 1 19:15:42 2018 +0200 avoid interactive mv diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am index 255650181..e6e0537e4 100644 --- a/bin/varnishd/Makefile.am +++ b/bin/varnishd/Makefile.am @@ -229,7 +229,7 @@ EXTRA_DIST = builtin.vcl vhp_hufdec.h: vhp_gen_hufdec $(AM_V_GEN) ./vhp_gen_hufdec > vhp_hufdec.h_ - mv vhp_hufdec.h_ vhp_hufdec.h + mv -f vhp_hufdec.h_ vhp_hufdec.h DISTCLEANFILES = builtin_vcl.c From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] ced282f1a Whitespace OCD Message-ID: <20180816085252.B89CC9B556@lists.varnish-cache.org> commit ced282f1ad2c97a35ba0da0c09255853eee1df51 Author: Dridi Boukelmoune Date: Wed May 2 08:29:23 2018 +0200 Whitespace OCD diff --git a/bin/varnishtest/tests/o00005.vtc b/bin/varnishtest/tests/o00005.vtc index 96154e82c..c9598fdf8 100644 --- a/bin/varnishtest/tests/o00005.vtc +++ b/bin/varnishtest/tests/o00005.vtc @@ -9,25 +9,25 @@ varnish v1 -proto "PROXY" -vcl+backend { import proxy; sub vcl_deliver { - if (proxy.is_ssl()) { - set resp.http.is_ssl = "yes"; - } - if (!proxy.client_has_cert_sess()) { - set resp.http.client_has_cert_sess = "no"; - } - if (!proxy.client_has_cert_conn()) { - set resp.http.client_has_cert_conn = "no"; - } - if (proxy.ssl_verify_result() == 0) { - set resp.http.verify = "ok"; - } - set resp.http.alpn = proxy.alpn(); - set resp.http.authority = proxy.authority(); - set resp.http.ssl-version = proxy.ssl_version(); - set resp.http.cipher = proxy.ssl_cipher(); - set resp.http.key = proxy.cert_key(); - set resp.http.sign = proxy.cert_sign(); - set resp.http.cn = proxy.client_cert_cn(); + if (proxy.is_ssl()) { + set resp.http.is_ssl = "yes"; + } + if (!proxy.client_has_cert_sess()) { + set resp.http.client_has_cert_sess = "no"; + } + if (!proxy.client_has_cert_conn()) { + set resp.http.client_has_cert_conn = "no"; + } + if (proxy.ssl_verify_result() == 0) { + set resp.http.verify = "ok"; + } + set resp.http.alpn = proxy.alpn(); + set resp.http.authority = proxy.authority(); + set resp.http.ssl-version = proxy.ssl_version(); + set resp.http.cipher = proxy.ssl_cipher(); + set resp.http.key = proxy.cert_key(); + set resp.http.sign = proxy.cert_sign(); + set resp.http.cn = proxy.client_cert_cn(); } } -start @@ -40,21 +40,22 @@ logexpect l1 -v v1 -g raw { client c1 { # PROXY2 with CRC32C TLV sendhex { - 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a - 21 11 00 65 - d9 46 b5 21 - 5f 8e a8 22 - ed 96 - 01 bb - 03 00 04 95 03 ee 75 - 01 00 02 68 32 - 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 - 20 00 3d + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 65 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + 03 00 04 95 03 ee 75 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d 01 00 00 00 00 21 00 07 54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 - 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq rxresp @@ -84,21 +85,22 @@ logexpect l1 -v v1 -g raw { client c1 { # PROXY2 with CRC32C TLV and bad checksum sendhex { - 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a - 21 11 00 65 - d9 46 b5 21 - 5f 8e a8 22 - ed 96 - 01 bb - 03 00 04 95 03 ee 74 - 01 00 02 68 32 - 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 - 20 00 3d + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 65 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + 03 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d 01 00 00 00 00 21 00 07 54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 - 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq expect_close @@ -116,22 +118,23 @@ logexpect l1 -v v1 -g raw { client c1 { # PROXY2 with CRC32C TLV and bad checksum sendhex { - 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a - 21 11 00 67 - d9 46 b5 21 - 5f 8e a8 22 - ed 96 - 01 bb - ff 00 04 95 03 ee 74 - 01 00 02 68 32 - 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 - 20 00 3d + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 67 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + ff 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d 01 00 00 00 00 21 00 07 54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 - 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 - ff ff + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 + 2d 47 43 4d 2d 53 48 41 32 35 36 + ff ff } txreq expect_close @@ -149,21 +152,22 @@ logexpect l1 -v v1 -g raw { client c1 { # PROXY2 with CRC32C TLV and bad checksum sendhex { - 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a - 21 11 00 60 - d9 46 b5 21 - 5f 8e a8 22 - ed 96 - 01 bb - ff 00 04 95 03 ee 74 - 01 00 02 68 32 - 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 - 20 00 3d + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 60 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + ff 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3d 01 00 00 00 00 21 00 07 54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 - 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq expect_close @@ -181,21 +185,22 @@ logexpect l1 -v v1 -g raw { client c1 { # PROXY2 with CRC32C TLV and bad checksum sendhex { - 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a - 21 11 00 65 - d9 46 b5 21 - 5f 8e a8 22 - ed 96 - 01 bb - ff 00 04 95 03 ee 74 - 01 00 02 68 32 - 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 - 20 00 3c + 0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a + 21 11 00 65 + d9 46 b5 21 + 5f 8e a8 22 + ed 96 + 01 bb + ff 00 04 95 03 ee 74 + 01 00 02 68 32 + 02 00 0a 68 6f 63 64 65 74 2e 6e 65 74 + 20 00 3c 01 00 00 00 00 21 00 07 54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 - 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53 48 41 32 35 36 + 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq expect_close @@ -204,4 +209,3 @@ client c1 { varnish v1 -vsl_catchup logexpect l1 -wait - From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:52 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:52 +0000 (UTC) Subject: [6.0] b4cb96933 Simplify o5.vtc Message-ID: <20180816085252.EC8799B587@lists.varnish-cache.org> commit b4cb96933a201756cf4de7b11d4b90ad78485d91 Author: Dridi Boukelmoune Date: Wed May 2 08:36:16 2018 +0200 Simplify o5.vtc diff --git a/bin/varnishtest/tests/o00005.vtc b/bin/varnishtest/tests/o00005.vtc index c9598fdf8..f1e92fc25 100644 --- a/bin/varnishtest/tests/o00005.vtc +++ b/bin/varnishtest/tests/o00005.vtc @@ -9,18 +9,10 @@ varnish v1 -proto "PROXY" -vcl+backend { import proxy; sub vcl_deliver { - if (proxy.is_ssl()) { - set resp.http.is_ssl = "yes"; - } - if (!proxy.client_has_cert_sess()) { - set resp.http.client_has_cert_sess = "no"; - } - if (!proxy.client_has_cert_conn()) { - set resp.http.client_has_cert_conn = "no"; - } - if (proxy.ssl_verify_result() == 0) { - set resp.http.verify = "ok"; - } + set resp.http.is_ssl = proxy.is_ssl(); + set resp.http.client_has_cert_sess = proxy.client_has_cert_sess(); + set resp.http.client_has_cert_conn = proxy.client_has_cert_conn(); + set resp.http.ssl_verify_result = proxy.ssl_verify_result() == 0; set resp.http.alpn = proxy.alpn(); set resp.http.authority = proxy.authority(); set resp.http.ssl-version = proxy.ssl_version(); @@ -60,10 +52,10 @@ client c1 { txreq rxresp expect resp.status == 200 - expect resp.http.is_ssl == yes - expect resp.http.client_has_cert_sess == no - expect resp.http.client_has_cert_conn == no - expect resp.http.verify == ok + expect resp.http.is_ssl == true + expect resp.http.client_has_cert_sess == false + expect resp.http.client_has_cert_conn == false + expect resp.http.ssl_verify_result == true expect resp.http.alpn == h2 expect resp.http.authority == hocdet.net expect resp.http.ssl-version == TLSv1.3 From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:53 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:53 +0000 (UTC) Subject: [6.0] 86f9768f4 One more take on http_gzip_support=off Message-ID: <20180816085253.202739B5AC@lists.varnish-cache.org> commit 86f9768f435462e167b183edde02d459bcda46d2 Author: Dridi Boukelmoune Date: Wed May 2 08:44:11 2018 +0200 One more take on http_gzip_support=off diff --git a/include/tbl/params.h b/include/tbl/params.h index 829f48f12..8cfb7f0f3 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -598,7 +598,11 @@ PARAM( "\n" "Clients that do not support gzip will have their Accept-Encoding " "header removed. For more information on how gzip is implemented " - "please see the chapter on gzip in the Varnish reference.", + "please see the chapter on gzip in the Varnish reference.\n" + "\n" + "When gzip support is disabled the variables beresp.do_gzip and " + "beresp.do_gunzip have no effect in VCL.", + /* XXX: what about the effect on beresp.filters? */ /* l-text */ "", /* func */ NULL ) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:53 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:53 +0000 (UTC) Subject: [6.0] a247f4487 Only handle signals if we still have a VUT Message-ID: <20180816085253.69BDB9B5C1@lists.varnish-cache.org> commit a247f4487aad8d7fb9404710c1235530d379794a Author: Dridi Boukelmoune Date: Wed May 2 10:37:24 2018 +0200 Only handle signals if we still have a VUT This can happen if a signal is caught after `VUT_Fini` was called, but at this point we should no longer manipulate the VUT being dismantled. Original test case by Geoff, slightly modified. Closes #2650 diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index b33f5ce73..5d32d6a80 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -494,7 +494,9 @@ profile_error(const char *s) static void vut_sighandler(int sig) { - VUT_Signaled(vut, sig); + + if (vut != NULL) + VUT_Signaled(vut, sig); } int diff --git a/bin/varnishlog/varnishlog.c b/bin/varnishlog/varnishlog.c index b714f54cb..d80986b78 100644 --- a/bin/varnishlog/varnishlog.c +++ b/bin/varnishlog/varnishlog.c @@ -124,8 +124,9 @@ sighup(struct VUT *v) static void vut_sighandler(int sig) { - CHECK_OBJ_NOTNULL(vut, VUT_MAGIC); - VUT_Signaled(vut, sig); + + if (vut != NULL) + VUT_Signaled(vut, sig); } int diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index cd3f5a027..488027d0e 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -1124,8 +1124,9 @@ sighup(struct VUT *v) static void vut_sighandler(int sig) { - CHECK_OBJ_NOTNULL(vut, VUT_MAGIC); - VUT_Signaled(vut, sig); + + if (vut != NULL) + VUT_Signaled(vut, sig); } static char * diff --git a/bin/varnishtest/tests/r02649.vtc b/bin/varnishtest/tests/r02649.vtc new file mode 100644 index 000000000..e8737b4f4 --- /dev/null +++ b/bin/varnishtest/tests/r02649.vtc @@ -0,0 +1,18 @@ +varnishtest "Cleanly stop a VUT app via vtc process -stop" + +varnish v1 -vcl { + backend be { + .host = "${bad_backend}"; + } +} -start + +process p1 { + exec varnishncsa -n ${v1_name} -P ${tmpdir}/ncsa.pid -w ${tmpdir}/ncsa.log +} -start + +delay 1 + +process p1 -expect-exit 0 -stop -wait + +# Expect empty stderr output +shell -match {^0\b} "wc -c ${tmpdir}/p1/stderr" diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 61f0e4d44..5f030c9a1 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -195,8 +195,9 @@ sighup(struct VUT *v) static void vut_sighandler(int sig) { - CHECK_OBJ_NOTNULL(vut, VUT_MAGIC); - VUT_Signaled(vut, sig); + + if (vut != NULL) + VUT_Signaled(vut, sig); } static void From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:53 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:53 +0000 (UTC) Subject: [6.0] 239bca372 Align the lifetime of the PID file to the VUT process Message-ID: <20180816085253.90C669B5CF@lists.varnish-cache.org> commit 239bca372c94c18880fcc8d4162f97db0815dc64 Author: Dridi Boukelmoune Date: Wed May 2 11:25:10 2018 +0200 Align the lifetime of the PID file to the VUT process For out-of-tree code that may set up multiple VUTs in a single process, we don't want the VUT that initialized a PID file to remove it if it finishes before other VUTs. A global pseudo-VUT is introduced to keep track of the PID file and the error callback in order to use them in the atexit(3) callback. Original test case by Geoff, slightly modified. Closes #2651 diff --git a/bin/varnishtest/tests/r02646.vtc b/bin/varnishtest/tests/r02646.vtc new file mode 100644 index 000000000..a5c3c432c --- /dev/null +++ b/bin/varnishtest/tests/r02646.vtc @@ -0,0 +1,21 @@ +varnishtest "#2646: VUT should fail gracefully when removing a pid file fails" + +varnish v1 -vcl { + backend be { + .host = "${bad_backend}"; + } +} -start + +process p1 { + exec varnishncsa -n ${v1_name} -P ${tmpdir}/ncsa.pid -w ${tmpdir}/ncsa.log +} -start + +delay 1 + +shell "rm -f ${tmpdir}/ncsa.pid" + +process p1 -expect-exit 1 -stop -wait + +shell -expect "Cannot remove pid file ${tmpdir}/ncsa.pid" { + cat ${tmpdir}/p1/stderr +} diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index e268326c1..a793e44a6 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -62,6 +62,8 @@ static int vut_options(const struct vopt_spec *); static struct vpf_fh *pfh; static unsigned daemonized; +static struct VUT pfh_vut; + static int vut_daemon(struct VUT *vut) { @@ -74,10 +76,18 @@ vut_daemon(struct VUT *vut) static void vut_vpf_remove(void) { - if (pfh != NULL) { - AZ(VPF_Remove(pfh)); - pfh = NULL; - } + + assert(VALID_OBJ(&pfh_vut, VUT_MAGIC)); + AN(pfh); + AN(pfh_vut.P_arg); + + if (VPF_Remove(pfh) != 0) + VUT_Error(&pfh_vut, 1, "Cannot remove pid file %s: %s", + pfh_vut.P_arg, strerror(errno)); + + free(pfh_vut.P_arg); + ZERO_OBJ(&pfh_vut, sizeof pfh_vut); + pfh = NULL; } static int v_matchproto_(VSLQ_dispatch_f) @@ -306,6 +316,13 @@ VUT_Setup(struct VUT *vut) if (vut->P_arg) { AN(pfh); AZ(VPF_Write(pfh)); + + /* NB: move ownership to a global pseudo-VUT. */ + INIT_OBJ(&pfh_vut, VUT_MAGIC); + pfh_vut.P_arg = vut->P_arg; + pfh_vut.error_f = vut->error_f; + vut->P_arg = NULL; + AZ(atexit(vut_vpf_remove)); } } @@ -319,13 +336,10 @@ VUT_Fini(struct VUT **vutp) AN(vut->progname); free(vut->n_arg); - free(vut->P_arg); free(vut->q_arg); free(vut->r_arg); free(vut->t_arg); - - vut_vpf_remove(); - AZ(pfh); + AZ(vut->P_arg); if (vut->vslq) VSLQ_Delete(&vut->vslq); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:53 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:53 +0000 (UTC) Subject: [6.0] 069ccecbc Drop VALID_OBJ for GCC Message-ID: <20180816085253.BC2B29B5E5@lists.varnish-cache.org> commit 069ccecbcef4567cd52f228fb5113b36661fbd92 Author: Dridi Boukelmoune Date: Wed May 2 11:53:53 2018 +0200 Drop VALID_OBJ for GCC It complains that &pfh_vut is never NULL... diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index a793e44a6..a34243b61 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -77,7 +77,7 @@ static void vut_vpf_remove(void) { - assert(VALID_OBJ(&pfh_vut, VUT_MAGIC)); + assert(pfh_vut.magic == VUT_MAGIC); AN(pfh); AN(pfh_vut.P_arg); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:53 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:53 +0000 (UTC) Subject: [6.0] e75d07835 Allow whitespace before wc(1) output Message-ID: <20180816085253.E6E969B5F7@lists.varnish-cache.org> commit e75d07835d0428a1b57cd41f61f438b414fd744e Author: Poul-Henning Kamp Date: Wed May 2 11:13:06 2018 +0000 Allow whitespace before wc(1) output diff --git a/bin/varnishtest/tests/r02649.vtc b/bin/varnishtest/tests/r02649.vtc index e8737b4f4..4ee5e414b 100644 --- a/bin/varnishtest/tests/r02649.vtc +++ b/bin/varnishtest/tests/r02649.vtc @@ -15,4 +15,4 @@ delay 1 process p1 -expect-exit 0 -stop -wait # Expect empty stderr output -shell -match {^0\b} "wc -c ${tmpdir}/p1/stderr" +shell -match {^[ ]*0\b} "wc -c ${tmpdir}/p1/stderr" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:54 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:54 +0000 (UTC) Subject: [6.0] be332215f Fix broken vsl-query example Message-ID: <20180816085254.1C0A49B610@lists.varnish-cache.org> commit be332215fb63ca7771e3b8626add4f7b2c8a68f3 Author: Dag Haavi Finstad Date: Wed May 2 16:40:12 2018 +0200 Fix broken vsl-query example diff --git a/doc/sphinx/reference/vsl-query.rst b/doc/sphinx/reference/vsl-query.rst index 891d36124..92b97c9e7 100644 --- a/doc/sphinx/reference/vsl-query.rst +++ b/doc/sphinx/reference/vsl-query.rst @@ -278,7 +278,7 @@ QUERY EXPRESSION EXAMPLES * Transaction group contains a request response status of 304, but where the request did not contain an if-modified-since header :: - ReqStatus == 304 and not ReqHeader:if-modified-since + RespStatus == 304 and not ReqHeader:if-modified-since * Transactions that have had backend failures or long delivery time on their ESI subrequests. (Assumes request grouping mode). :: From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:54 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:54 +0000 (UTC) Subject: [6.0] e7a491a71 Don't bother with the return value from H2_Send(), we rely on h2_errcheck() calls anyway. Message-ID: <20180816085254.47E0B9B636@lists.varnish-cache.org> commit e7a491a711ef51eed38fc3581735308ab77d7849 Author: Poul-Henning Kamp Date: Wed May 2 22:17:58 2018 +0000 Don't bother with the return value from H2_Send(), we rely on h2_errcheck() calls anyway. diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h index cfe8598fd..a1d6f849b 100644 --- a/bin/varnishd/http2/cache_http2.h +++ b/bin/varnishd/http2/cache_http2.h @@ -220,7 +220,7 @@ h2_error H2_Send_Frame(struct worker *, const struct h2_sess *, h2_frame type, uint8_t flags, uint32_t len, uint32_t stream, const void *); -h2_error H2_Send(struct worker *, struct h2_req *, +void H2_Send(struct worker *, struct h2_req *, h2_frame type, uint8_t flags, uint32_t len, const void *); /* cache_http2_proto.c */ diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c index a0ff969e6..2b7f695fa 100644 --- a/bin/varnishd/http2/cache_http2_deliver.c +++ b/bin/varnishd/http2/cache_http2_deliver.c @@ -91,8 +91,8 @@ h2_bytes(struct req *req, enum vdp_action act, void **priv, H2_F_DATA, act == VDP_FINI ? H2FF_DATA_END_STREAM : H2FF_NONE, len, ptr); - req->acct.resp_bodybytes += len; H2_Send_Rel(r2->h2sess, r2); + req->acct.resp_bodybytes += len; return (0); } @@ -260,8 +260,8 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) H2_Send(req->wrk, r2, H2_F_HEADERS, (sendbody ? 0 : H2FF_HEADERS_END_STREAM) | H2FF_HEADERS_END_HEADERS, sz, req->ws->f); - req->acct.resp_hdrbytes += sz; H2_Send_Rel(r2->h2sess, r2); + req->acct.resp_hdrbytes += sz; WS_Release(req->ws, 0); diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index 839193fd0..cfbb51be7 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -245,7 +245,7 @@ h2_do_window(struct worker *wrk, struct h2_req *r2, * XXX: priority */ -h2_error +void H2_Send(struct worker *wrk, struct h2_req *r2, h2_frame ftyp, uint8_t flags, uint32_t len, const void *ptr) { @@ -263,9 +263,8 @@ H2_Send(struct worker *wrk, struct h2_req *r2, assert(VTAILQ_FIRST(&h2->txqueue) == r2); - retval = h2_errcheck(r2, h2); - if (retval) - return (retval); + if (h2_errcheck(r2, h2)) + return; AN(ftyp); AZ(flags & ~(ftyp->flags)); @@ -281,15 +280,14 @@ H2_Send(struct worker *wrk, struct h2_req *r2, if (ftyp->respect_window) { tf = h2_do_window(wrk, r2, h2, (len > mfs) ? mfs : len); - retval = h2_errcheck(r2, h2); - if (retval) - return (retval); + if (h2_errcheck(r2, h2)) + return; assert(VTAILQ_FIRST(&h2->txqueue) == r2); } else tf = mfs; if (len <= tf) { - retval = H2_Send_Frame(wrk, h2, + (void)H2_Send_Frame(wrk, h2, ftyp, flags, len, r2->stream, ptr); } else { AN(ptr); @@ -303,9 +301,8 @@ H2_Send(struct worker *wrk, struct h2_req *r2, if (ftyp->respect_window && p != ptr) { tf = h2_do_window(wrk, r2, h2, (len > mfs) ? mfs : len); - retval = h2_errcheck(r2, h2); - if (retval) - return (retval); + if (h2_errcheck(r2, h2)) + return; assert(VTAILQ_FIRST(&h2->txqueue) == r2); } if (tf < len) { @@ -324,5 +321,4 @@ H2_Send(struct worker *wrk, struct h2_req *r2, ftyp = ftyp->continuation; } while (len > 0 && retval == 0); } - return (retval); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:54 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:54 +0000 (UTC) Subject: [6.0] 38d515a99 Unbogotify slightly Message-ID: <20180816085254.7725C9B64A@lists.varnish-cache.org> commit 38d515a992f6bf572965b6bf31e9f19bcdc41cfa Author: Poul-Henning Kamp Date: Wed May 2 22:52:55 2018 +0000 Unbogotify slightly diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c index 2b7f695fa..cb9c7d3f2 100644 --- a/bin/varnishd/http2/cache_http2_deliver.c +++ b/bin/varnishd/http2/cache_http2_deliver.c @@ -266,12 +266,10 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) WS_Release(req->ws, 0); /* XXX someone into H2 please add appropriate error handling */ - while (sendbody) { + if (sendbody) { err = VDP_push(req, &h2_vdp, NULL, 1); - if (err) - break; - err = VDP_DeliverObj(req); - break; + if (!err) + err = VDP_DeliverObj(req); } AZ(req->wrk->v1l); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:54 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:54 +0000 (UTC) Subject: [6.0] 636d489e2 Polish Message-ID: <20180816085254.9D59E9B658@lists.varnish-cache.org> commit 636d489e2918fc5db56f817c92c27bc89b18c08e Author: Federico G. Schwindt Date: Thu May 3 06:32:12 2018 +0200 Polish diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index a34243b61..5a0477053 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -77,7 +77,7 @@ static void vut_vpf_remove(void) { - assert(pfh_vut.magic == VUT_MAGIC); + CHECK_OBJ(&pfh_vut, VUT_MAGIC); AN(pfh); AN(pfh_vut.P_arg); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:54 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:54 +0000 (UTC) Subject: [6.0] 17e14997e Do not silence address or pointer-sign warnings Message-ID: <20180816085254.C64B99B66C@lists.varnish-cache.org> commit 17e14997e3d169ac8584014bf43425e87321da27 Author: Federico G. Schwindt Date: Thu May 3 08:02:50 2018 +0200 Do not silence address or pointer-sign warnings After recent failures discovered by travis-ci it should be safe to have this back on. diff --git a/configure.ac b/configure.ac index 17c6f17c9..bda22723e 100644 --- a/configure.ac +++ b/configure.ac @@ -644,15 +644,8 @@ AC_ARG_ENABLE(developer-warnings, [enable_developer_warnings=no]) if test "x$SUNCC" != "xyes" && test "x$enable_developer_warnings" != "xno"; then - # compiler flags not available on gcc3 - AX_CHECK_COMPILE_FLAG([-Wno-pointer-sign], - [DEVELOPER_CFLAGS="${DEVELOPER_CFLAGS} -Wno-pointer-sign"], [], []) - # Not available in gcc 4.1.2 - AX_CHECK_COMPILE_FLAG([-Wno-address], - [DEVELOPER_CFLAGS="${DEVELOPER_CFLAGS} -Wno-address"]) - - # no known way to specifically disabling missing-field-initializers warnings - # keeping the rest of Wextra + # no known way to specifically disabling missing-field-initializers + # warnings keeping the rest of Wextra AX_CHECK_COMPILE_FLAG([-Wno-missing-field-initializers], [DEVELOPER_CFLAGS="${DEVELOPER_CFLAGS} -Wno-missing-field-initializers"], [DEVELOPER_CFLAGS="${DEVELOPER_CFLAGS} -Wno-extra"], From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:54 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:54 +0000 (UTC) Subject: [6.0] 3a27bc8e8 polish Message-ID: <20180816085254.F21D89B676@lists.varnish-cache.org> commit 3a27bc8e84841f9d657051f05485fd9bb006378d Author: Nils Goroll Date: Thu May 3 13:40:56 2018 +0200 polish diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index 77315f5b5..a50ff2f4b 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -806,8 +806,7 @@ shard_param_task(VRT_CTX, const void *id, } if (task->priv) { - p = task->priv; - CHECK_OBJ_NOTNULL(p, VMOD_SHARD_SHARD_PARAM_MAGIC); + CAST_OBJ_NOTNULL(p, task->priv, VMOD_SHARD_SHARD_PARAM_MAGIC); assert(p->scope == SCOPE_TASK); /* XXX VSL(SLT_Debug, 0, From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:55 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:55 +0000 (UTC) Subject: [6.0] a87ebb065 constify storage ident Message-ID: <20180816085255.25D9B9B68E@lists.varnish-cache.org> commit a87ebb06507c8a61e9235c82c658f42205f16b32 Author: Nils Goroll Date: Sat May 5 10:11:08 2018 +0200 constify storage ident diff --git a/bin/varnishd/storage/storage.h b/bin/varnishd/storage/storage.h index 08f23c9af..212142ceb 100644 --- a/bin/varnishd/storage/storage.h +++ b/bin/varnishd/storage/storage.h @@ -119,8 +119,8 @@ struct stevedore { void *priv; VTAILQ_ENTRY(stevedore) list; - char *ident; - char *vclname; + const char *ident; + const char *vclname; }; extern struct stevedore *stv_transient; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:55 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:55 +0000 (UTC) Subject: [6.0] 861085142 plug minor leaks reported by coverity Message-ID: <20180816085255.5BF279B6B3@lists.varnish-cache.org> commit 86108514270a4cef7fc9d40a2e7b9ad15dd805c1 Author: Nils Goroll Date: Sat May 5 10:17:56 2018 +0200 plug minor leaks reported by coverity diff --git a/bin/varnishd/storage/mgt_stevedore.c b/bin/varnishd/storage/mgt_stevedore.c index a37ddf335..32779a9c6 100644 --- a/bin/varnishd/storage/mgt_stevedore.c +++ b/bin/varnishd/storage/mgt_stevedore.c @@ -189,12 +189,12 @@ STV_Config(const char *spec) *stv = *stv2; AN(stv->name); - if (name == NULL) { + if (name) { + stv->ident = name; + } else { bprintf(buf, "s%u", seq++); - name = buf; + stv->ident = strdup(buf); } - - stv->ident = strdup(name); AN(stv->ident); stv_check_ident(spec, stv->ident); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 08977af28..b0efed5e3 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -300,6 +300,7 @@ vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t, ExpectErr(tl, CSTR); p = vcc_regexp(tl); bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n%s", all, p); + free(TRUST_ME(p)); *e = vcc_expr_edit(tl, STRING, buf, e2, NULL); SkipToken(tl, ','); vcc_expr0(tl, &e2, STRING); @@ -990,6 +991,7 @@ cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp) re = vcc_regexp(tl); ERRCHK(tl); bprintf(buf, "%sVRT_re_match(ctx, \v1, %s)", cp->emit, re); + free(TRUST_ME(re)); *e = vcc_expr_edit(tl, BOOL, buf, *e, NULL); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:55 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:55 +0000 (UTC) Subject: [6.0] 058675584 rename variable for clarity Message-ID: <20180816085255.808699B6C7@lists.varnish-cache.org> commit 0586755847c792ae56bdd9a0b61a0252a692cdf8 Author: Nils Goroll Date: Sat May 5 10:22:01 2018 +0200 rename variable for clarity diff --git a/bin/varnishd/storage/mgt_stevedore.c b/bin/varnishd/storage/mgt_stevedore.c index 32779a9c6..3f66c3af3 100644 --- a/bin/varnishd/storage/mgt_stevedore.c +++ b/bin/varnishd/storage/mgt_stevedore.c @@ -159,13 +159,13 @@ void STV_Config(const char *spec) { char **av, buf[8]; - const char *name; + const char *ident; struct stevedore *stv; const struct stevedore *stv2; int ac; static unsigned seq = 0; - av = MGT_NamedArg(spec, &name, "-s"); + av = MGT_NamedArg(spec, &ident, "-s"); AN(av); if (av[1] == NULL) @@ -189,8 +189,8 @@ STV_Config(const char *spec) *stv = *stv2; AN(stv->name); - if (name) { - stv->ident = name; + if (ident) { + stv->ident = ident; } else { bprintf(buf, "s%u", seq++); stv->ident = strdup(buf); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:55 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:55 +0000 (UTC) Subject: [6.0] 6f65332ee MAIN.summs documentation Message-ID: <20180816085255.BBEC39B6D6@lists.varnish-cache.org> commit 6f65332eeb5cd88b9c58c7d0a933e8260d81d2d8 Author: Nils Goroll Date: Mon May 7 14:45:44 2018 +0200 MAIN.summs documentation Ref #2672 diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc index fd9a4e682..4fe84d849 100644 --- a/bin/varnishd/VSC_main.vsc +++ b/bin/varnishd/VSC_main.vsc @@ -11,6 +11,9 @@ :level: debug :oneliner: stat summ operations + Numer of times per-thread statistics were added to the + global counters. + .. varnish_vsc:: uptime :oneliner: Child process uptime :format: duration From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:55 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:55 +0000 (UTC) Subject: [6.0] 034cb4f17 fix typo Message-ID: <20180816085255.DF2199B6DF@lists.varnish-cache.org> commit 034cb4f17965fce56ac03ba0c6ae1143ba550470 Author: Nils Goroll Date: Mon May 7 15:05:47 2018 +0200 fix typo spotted by @lkarsten diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc index 4fe84d849..a2e2d0143 100644 --- a/bin/varnishd/VSC_main.vsc +++ b/bin/varnishd/VSC_main.vsc @@ -11,7 +11,7 @@ :level: debug :oneliner: stat summ operations - Numer of times per-thread statistics were added to the + Number of times per-thread statistics were added to the global counters. .. varnish_vsc:: uptime From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:56 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:56 +0000 (UTC) Subject: [6.0] 634c709fe allocate dynamic privs on the appropriate workspace Message-ID: <20180816085256.18CEB9B6F1@lists.varnish-cache.org> commit 634c709fefcc4a7bc1a76e95b41d768c7d5a2e5f Author: Nils Goroll Date: Thu May 3 13:27:31 2018 +0200 allocate dynamic privs on the appropriate workspace A show stopper used to be that the top request's workspace was reserved for delivery during ESI processing, but since beeaa19cced3fe1ab79381b2b1b7b0b5594cbb18 the path is clear. diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 9580a3247..245a4b813 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -92,24 +92,25 @@ VRTPRIV_init(struct vrt_privs *privs) } static struct vmod_priv * -vrt_priv_dynamic(VRT_CTX, struct vrt_privs *vps, uintptr_t id, - uintptr_t vmod_id) +vrt_priv_dynamic(const struct vcl *vcl, struct ws *ws, + struct vrt_privs *vps, uintptr_t id, uintptr_t vmod_id) { struct vrt_priv *vp; - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vps, VRT_PRIVS_MAGIC); AN(vmod_id); VTAILQ_FOREACH(vp, &vps->privs, list) { CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC); - if (vp->vcl == ctx->vcl && vp->id == id && + if (vp->vcl == vcl && vp->id == id && vp->vmod_id == vmod_id) return (vp->priv); } - ALLOC_OBJ(vp, VRT_PRIV_MAGIC); - AN(vp); - vp->vcl = ctx->vcl; + vp = WS_Alloc(ws, sizeof *vp); + if (vp == NULL) + return NULL; + INIT_OBJ(vp, VRT_PRIV_MAGIC); + vp->vcl = vcl; vp->id = id; vp->vmod_id = vmod_id; VTAILQ_INSERT_TAIL(&vps->privs, vp, list); @@ -129,7 +130,6 @@ VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id) if (id == vp->id) { VTAILQ_REMOVE(&privs->privs, vp, list); VRT_priv_fini(vp->priv); - FREE_OBJ(vp); } } } @@ -154,7 +154,8 @@ VRT_priv_task(VRT_CTX, const void *vmod_id) id = (uintptr_t)cli_task_privs; CAST_OBJ_NOTNULL(vps, cli_task_privs, VRT_PRIVS_MAGIC); } - return (vrt_priv_dynamic(ctx, vps, id, (uintptr_t)vmod_id)); + return (vrt_priv_dynamic(ctx->vcl, ctx->ws, + vps, id, (uintptr_t)vmod_id)); } struct vmod_priv * @@ -169,7 +170,8 @@ VRT_priv_top(VRT_CTX, const void *vmod_id) CHECK_OBJ_NOTNULL(ctx->req->top, REQ_MAGIC); id = (uintptr_t)&ctx->req->top->top; CAST_OBJ_NOTNULL(vps, ctx->req->top->privs, VRT_PRIVS_MAGIC); - return (vrt_priv_dynamic(ctx, vps, id, (uintptr_t)vmod_id)); + return (vrt_priv_dynamic(ctx->vcl, ctx->req->top->ws, + vps, id, (uintptr_t)vmod_id)); } else WRONG("PRIV_TOP is only accessible in client VCL context"); NEEDLESS(return NULL); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:56 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:56 +0000 (UTC) Subject: [6.0] 0af9cac1b Add a copyright to this file Message-ID: <20180816085256.4FB929B717@lists.varnish-cache.org> commit 0af9cac1ba5f3ac0be7c209d911b68d4eec7a334 Author: Poul-Henning Kamp Date: Mon May 7 21:44:11 2018 +0000 Add a copyright to this file diff --git a/bin/varnishtest/vtc_h2_priv.h b/bin/varnishtest/vtc_h2_priv.h index 706ba0c1d..796e94049 100644 --- a/bin/varnishtest/vtc_h2_priv.h +++ b/bin/varnishtest/vtc_h2_priv.h @@ -1,3 +1,31 @@ +/*- + * Copyright (c) 2008-2016 Varnish Software AS + * All rights reserved. + * + * Author: Guillaume Quintard + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + #include "vqueue.h" #define ITER_DONE(iter) (iter->buf == iter->end ? hpk_done : hpk_more) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:56 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:56 +0000 (UTC) Subject: [6.0] c163ab221 A little bit of flexelintery Message-ID: <20180816085256.77EC29B72A@lists.varnish-cache.org> commit c163ab221fb9da7492f84ac452c889452c154177 Author: Poul-Henning Kamp Date: Mon May 7 21:50:25 2018 +0000 A little bit of flexelintery diff --git a/bin/varnishtest/flint.lnt b/bin/varnishtest/flint.lnt index 78c17a9c7..6e392f2d6 100644 --- a/bin/varnishtest/flint.lnt +++ b/bin/varnishtest/flint.lnt @@ -10,6 +10,8 @@ -emacro({779}, ENC) // String constant in comparison operator '!=' -emacro({506}, CHKFRAME) // Constant value Boolean +-sem(http_process_cleanup, custodial(1)) + -esym(522, teken_subr_*) -esym(850, av) diff --git a/bin/varnishtest/vtc_h2_hpack.c b/bin/varnishtest/vtc_h2_hpack.c index 9b6f25080..403db13a8 100644 --- a/bin/varnishtest/vtc_h2_hpack.c +++ b/bin/varnishtest/vtc_h2_hpack.c @@ -259,7 +259,7 @@ str_decode(struct hpk_iter *iter, struct txt *t) if (num > iter->end - iter->buf) return (hpk_err); if (huff) { /*Huffman encoding */ - t->ptr = malloc((num * 8) / 5L + 1L); + t->ptr = malloc((num * 8L) / 5L + 1L); AN(t->ptr); num = huff_decode(t->ptr, (num * 8) / 5, iter, num); if (!num) { diff --git a/bin/varnishtest/vtc_process.c b/bin/varnishtest/vtc_process.c index 5e3816bca..95f6c0517 100644 --- a/bin/varnishtest/vtc_process.c +++ b/bin/varnishtest/vtc_process.c @@ -320,7 +320,7 @@ term_expect_text(struct process *pp, } static void -term_expect_cursor(struct process *pp, const char *lin, const char *col) +term_expect_cursor(const struct process *pp, const char *lin, const char *col) { int x, y; const teken_pos_t *pos; diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 294305840..33ead868e 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -327,7 +327,7 @@ server_dispatch_thread(void *priv) vtc_log(vl, 2, "Dispatch started on %s", s->listen); - while (1) { + while (!vtc_stop) { addr = (void*)&addr_s; l = sizeof addr_s; fd = accept(s->sock, addr, &l); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:56 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:56 +0000 (UTC) Subject: [6.0] 866eb9dd0 create a char * argument for umem_cache_create() Message-ID: <20180816085256.9CEA59B73D@lists.varnish-cache.org> commit 866eb9dd0715b923e7ea414495d75adb7903e294 Author: Nils Goroll Date: Tue May 8 10:09:54 2018 +0200 create a char * argument for umem_cache_create() required after the constification in 8f83087f333109ab12d82864b8e7ac98c132cf82 I have no idea why the umem authors did not make this argument a const, they call strncpy on it diff --git a/bin/varnishd/storage/storage_umem.c b/bin/varnishd/storage/storage_umem.c index e36693974..ace90356e 100644 --- a/bin/varnishd/storage/storage_umem.c +++ b/bin/varnishd/storage/storage_umem.c @@ -392,6 +392,7 @@ static void v_matchproto_(storage_open_f) smu_open(struct stevedore *st) { struct smu_sc *smu_sc; + char ident[strlen(st->ident) + 1]; ASSERT_CLI(); st->lru = LRU_Alloc(); @@ -405,7 +406,8 @@ smu_open(struct stevedore *st) smu_open_init(); - smu_sc->smu_cache = umem_cache_createf(st->ident, + AN(strcpy(ident, st->ident)); + smu_sc->smu_cache = umem_cache_createf(ident, sizeof(struct smu), 0, // align smu_smu_constructor, From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:56 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:56 +0000 (UTC) Subject: [6.0] 0162c22d8 Formatting Message-ID: <20180816085256.D46709B751@lists.varnish-cache.org> commit 0162c22d80de4953f9fd34fcaa925192c658c06f Author: Dag Haavi Finstad Date: Tue May 8 11:50:23 2018 +0200 Formatting diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 245a4b813..8d83f176c 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -108,7 +108,7 @@ vrt_priv_dynamic(const struct vcl *vcl, struct ws *ws, } vp = WS_Alloc(ws, sizeof *vp); if (vp == NULL) - return NULL; + return (NULL); INIT_OBJ(vp, VRT_PRIV_MAGIC); vp->vcl = vcl; vp->id = id; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:56 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:56 +0000 (UTC) Subject: [6.0] be37f8307 avoid TRUST_ME in shard director Message-ID: <20180816085257.0075F9B759@lists.varnish-cache.org> commit be37f8307fba209b6dada5bab665ed9d2cbf4735 Author: Nils Goroll Date: Tue May 8 17:13:37 2018 +0200 avoid TRUST_ME in shard director diff --git a/lib/libvmod_directors/shard_cfg.c b/lib/libvmod_directors/shard_cfg.c index 4674a40e9..54735953d 100644 --- a/lib/libvmod_directors/shard_cfg.c +++ b/lib/libvmod_directors/shard_cfg.c @@ -293,8 +293,8 @@ shardcfg_hashcircle(struct sharddir *shardd, VCL_INT replicas) static void shardcfg_backend_free(struct shard_backend *f) { - if (f->ident) - free (TRUST_ME(f->ident)); + if (f->freeptr) + free (f->freeptr); memset(f, 0, sizeof(*f)); } diff --git a/lib/libvmod_directors/shard_dir.h b/lib/libvmod_directors/shard_dir.h index f1b1b008c..eeb17df64 100644 --- a/lib/libvmod_directors/shard_dir.h +++ b/lib/libvmod_directors/shard_dir.h @@ -57,7 +57,10 @@ struct shard_circlepoint { struct shard_backend { VCL_BACKEND backend; - const char *ident; // XXX COPY IN ! + union { + const char *ident; + void *freeptr; + }; VCL_DURATION rampup; uint32_t canon_point; }; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:57 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:57 +0000 (UTC) Subject: [6.0] 5046ccc8e use a vsb to return vcc_regexp's result Message-ID: <20180816085257.24E1A9B773@lists.varnish-cache.org> commit 5046ccc8e3bb3ab3e8f54ea1dd6871fa12b1fe45 Author: Nils Goroll Date: Tue May 8 17:50:33 2018 +0200 use a vsb to return vcc_regexp's result to avoid micro-managing memory Follow up cf20e04efa007be1632c9f137338203f9691d25a diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index f5300958b..fef82ecef 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -322,7 +322,7 @@ void vcc_Parse_Init(struct vcc *); sym_act_f vcc_Act_If; /* vcc_utils.c */ -const char *vcc_regexp(struct vcc *tl); +void vcc_regexp(struct vcc *tl, struct vsb *vgc_name); void Resolve_Sockaddr(struct vcc *tl, const char *host, const char *defport, const char **ipv4, const char **ipv4_ascii, const char **ipv6, const char **ipv6_ascii, const char **p_ascii, int maxips, diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index b0efed5e3..37bfb04ed 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -288,8 +288,8 @@ vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t, { struct expr *e2; int all = sym->eval_priv == NULL ? 0 : 1; - const char *p; char buf[128]; + struct vsb vsb; (void)t; (void)fmt; @@ -298,10 +298,13 @@ vcc_Eval_Regsub(struct vcc *tl, struct expr **e, struct token *t, ERRCHK(tl); SkipToken(tl, ','); ExpectErr(tl, CSTR); - p = vcc_regexp(tl); - bprintf(buf, "VRT_regsub(ctx, %d,\v+\n\v1,\n%s", all, p); - free(TRUST_ME(p)); - *e = vcc_expr_edit(tl, STRING, buf, e2, NULL); + + AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN)); + VSB_printf(&vsb, "VRT_regsub(ctx, %d,\v+\n\v1,\n", all); + vcc_regexp(tl, &vsb); + ERRCHK(tl); + AZ(VSB_finish(&vsb)); + *e = vcc_expr_edit(tl, STRING, VSB_data(&vsb), e2, NULL); SkipToken(tl, ','); vcc_expr0(tl, &e2, STRING); ERRCHK(tl); @@ -983,16 +986,18 @@ static void v_matchproto_(cmp_f) cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp) { char buf[128]; - const char *re; + struct vsb vsb; *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL); vcc_NextToken(tl); ExpectErr(tl, CSTR); - re = vcc_regexp(tl); + AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN)); + VSB_printf(&vsb, "%sVRT_re_match(ctx, \v1, ", cp->emit); + vcc_regexp(tl, &vsb); ERRCHK(tl); - bprintf(buf, "%sVRT_re_match(ctx, \v1, %s)", cp->emit, re); - free(TRUST_ME(re)); - *e = vcc_expr_edit(tl, BOOL, buf, *e, NULL); + VSB_cat(&vsb, ")"); + AZ(VSB_finish(&vsb)); + *e = vcc_expr_edit(tl, BOOL, VSB_data(&vsb), *e, NULL); } static void v_matchproto_(cmp_f) diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 33e2aa6a2..71db6a792 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -47,10 +47,10 @@ /*--------------------------------------------------------------------*/ -const char * -vcc_regexp(struct vcc *tl) +void +vcc_regexp(struct vcc *tl, struct vsb *vgc_name) { - char buf[BUFSIZ], *p; + char buf[BUFSIZ]; vre_t *t; const char *error; int erroroffset; @@ -58,18 +58,18 @@ vcc_regexp(struct vcc *tl) Expect(tl, CSTR); if (tl->err) - return (NULL); + return; t = VRE_compile(tl->t->dec, 0, &error, &erroroffset); if (t == NULL) { VSB_printf(tl->sb, "Regexp compilation error:\n\n%s\n\n", error); vcc_ErrWhere(tl, tl->t); - return (NULL); + return; } VRE_free(&t); bprintf(buf, "VGC_re_%u", tl->unique++); - p = TlAlloc(tl, strlen(buf) + 1); - strcpy(p, buf); + if (vgc_name) + VSB_cat(vgc_name, buf); Fh(tl, 0, "static void *%s;\n", buf); ifp = New_IniFin(tl); @@ -78,7 +78,6 @@ vcc_regexp(struct vcc *tl) VSB_printf(ifp->ini, ");"); VSB_printf(ifp->fin, "\t\tVRT_re_fini(%s);", buf); vcc_NextToken(tl); - return (p); } /* From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:57 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:57 +0000 (UTC) Subject: [6.0] 84c88f6d2 Whitespace OCD Message-ID: <20180816085257.517169B795@lists.varnish-cache.org> commit 84c88f6d211dc11d74f3175020c046424925b68e Author: Poul-Henning Kamp Date: Sun May 13 14:22:21 2018 +0000 Whitespace OCD diff --git a/bin/varnishtest/tests/o00005.vtc b/bin/varnishtest/tests/o00005.vtc index f1e92fc25..3ec7a2881 100644 --- a/bin/varnishtest/tests/o00005.vtc +++ b/bin/varnishtest/tests/o00005.vtc @@ -47,7 +47,7 @@ client c1 { 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 - 2d 47 43 4d 2d 53 48 41 32 35 36 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq rxresp @@ -92,7 +92,7 @@ client c1 { 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 - 2d 47 43 4d 2d 53 48 41 32 35 36 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq expect_close @@ -125,7 +125,7 @@ client c1 { 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 - 2d 47 43 4d 2d 53 48 41 32 35 36 + 2d 47 43 4d 2d 53 48 41 32 35 36 ff ff } txreq @@ -159,7 +159,7 @@ client c1 { 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 - 2d 47 43 4d 2d 53 48 41 32 35 36 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq expect_close @@ -192,7 +192,7 @@ client c1 { 25 00 05 45 43 32 35 36 24 00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41 45 41 44 2d 41 45 53 31 32 38 - 2d 47 43 4d 2d 53 48 41 32 35 36 + 2d 47 43 4d 2d 53 48 41 32 35 36 } txreq expect_close diff --git a/bin/varnishtest/tests/r02649.vtc b/bin/varnishtest/tests/r02649.vtc index 4ee5e414b..71cd3483c 100644 --- a/bin/varnishtest/tests/r02649.vtc +++ b/bin/varnishtest/tests/r02649.vtc @@ -15,4 +15,4 @@ delay 1 process p1 -expect-exit 0 -stop -wait # Expect empty stderr output -shell -match {^[ ]*0\b} "wc -c ${tmpdir}/p1/stderr" +shell -match {^[ ]*0\b} "wc -c ${tmpdir}/p1/stderr" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:57 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:57 +0000 (UTC) Subject: [6.0] 32a56bba5 Pass -j args to child Message-ID: <20180816085257.7669D9B7B6@lists.varnish-cache.org> commit 32a56bba5f218b20849c2cd2ce9c5cb81032350f Author: Poul-Henning Kamp Date: Sun May 13 15:09:04 2018 +0000 Pass -j args to child diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c index bc9c2a78f..3304ef03c 100644 --- a/bin/varnishd/mgt/mgt_cli.c +++ b/bin/varnishd/mgt/mgt_cli.c @@ -162,10 +162,10 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv) } static const struct cli_cmd_desc CLICMD_WILDCARD[1] = - {{ "*", "", "", "", 0, -1 }}; + {{ "*", "", "", "", 0, 999 }}; static struct cli_proto cli_askchild[] = { - { CLICMD_WILDCARD, "h*", mcf_askchild }, + { CLICMD_WILDCARD, "h*", mcf_askchild, mcf_askchild }, { NULL } }; diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index a5e671490..67c681642 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -215,7 +215,7 @@ cls_dispatch(struct cli *cli, const struct cli_proto *cp, return; } - if (ac - 1> cp->desc->maxarg + json) { + if (ac - 1 > cp->desc->maxarg + json) { VCLI_Out(cli, "Too many parameters\n"); VCLI_SetResult(cli, CLIS_TOOMANY); return; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:57 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:57 +0000 (UTC) Subject: [6.0] 980a4a9e8 Add -clijson, which checks that CLI output can be parsed as JSON Message-ID: <20180816085257.9E1D99B7CB@lists.varnish-cache.org> commit 980a4a9e8eda9343687c61f1736e22f5787d9660 Author: Poul-Henning Kamp Date: Sun May 13 20:30:29 2018 +0000 Add -clijson, which checks that CLI output can be parsed as JSON diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index a688b62a2..b7304b50d 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -47,6 +47,7 @@ #include "vapi/vsl.h" #include "vapi/vsm.h" #include "vcli.h" +#include "vjsn.h" #include "vre.h" #include "vsub.h" #include "vtcp.h" @@ -655,6 +656,34 @@ varnish_wait(struct varnish *v) } +/********************************************************************** + * Ask a CLI JSON question + */ + +static void +varnish_cli_json(struct varnish *v, const char *cli) +{ + enum VCLI_status_e u; + char *resp = NULL; + const char *errptr; + struct vjsn *vj; + + if (v->cli_fd < 0) + varnish_launch(v); + if (vtc_error) + return; + u = varnish_ask_cli(v, cli, &resp); + vtc_log(v->vl, 2, "CLI %03u <%s>", u, cli); + if (u != CLIS_OK) + vtc_fatal(v->vl, + "FAIL CLI response %u expected %u", u, CLIS_OK); + vj = vjsn_parse(resp, &errptr); + if (vj == NULL) + vtc_fatal(v->vl, "FAIL CLI, not good JSON: %s", errptr); + vjsn_delete(&vj); + free(resp); +} + /********************************************************************** * Ask a CLI question */ @@ -1005,7 +1034,7 @@ varnish_expect(const struct varnish *v, char * const *av) * ``varnishadm``) with these additional switches:: * * varnish vNAME [-cli STRING] [-cliok STRING] [-clierr STRING] - * [-expect STRING OP NUMBER] + * [-clijson STRING] [-expect STRING OP NUMBER] * * \-cli STRING|-cliok STRING|-clierr STATUS STRING|-cliexpect REGEXP STRING * All four of these will send STRING to the CLI, the only difference @@ -1013,6 +1042,10 @@ varnish_expect(const struct varnish *v, char * const *av) * anything, -cliok expects 200, -clierr expects STATUS, and * -cliexpect expects the REGEXP to match the returned response. * + * \-clijson STRING + * Send STRING to the CLI, expect success (CLIS_OK/200) and check + * that the response is parsable JSON. + * * \-expect PATTERN OP NUMBER * Look into the VSM and make sure the first VSC counter identified by * PATTERN has a correct value. OP can be ==, >, >=, <, <=. For @@ -1099,6 +1132,12 @@ cmd_varnish(CMD_ARGS) av += 2; continue; } + if (!strcmp(*av, "-clijson")) { + AN(av[1]); + varnish_cli_json(v, av[1]); + av++; + continue; + } if (!strcmp(*av, "-cliok")) { AN(av[1]); varnish_cli(v, av[1], (unsigned)CLIS_OK, NULL); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:57 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:57 +0000 (UTC) Subject: [6.0] c6c636217 Make help -j output real JSON, and push backend.list -j into the schema intended for JSON output. Message-ID: <20180816085257.C41BD9B7E2@lists.varnish-cache.org> commit c6c6362170ddbe918ed1c2d2702ce77b2d76f987 Author: Poul-Henning Kamp Date: Sun May 13 20:52:10 2018 +0000 Make help -j output real JSON, and push backend.list -j into the schema intended for JSON output. Conflicts: bin/varnishd/cache/cache_backend.c bin/varnishd/cache/cache_backend_probe.c bin/varnishd/cache/cache_director.c bin/varnishtest/tests/d00005.vtc bin/varnishtest/tests/v00014.vtc Only help -j is fixed, the backend changes are left out. diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc index e536a81ee..1ec361155 100644 --- a/bin/varnishtest/tests/b00008.vtc +++ b/bin/varnishtest/tests/b00008.vtc @@ -26,7 +26,7 @@ varnish v1 -start varnish v1 -cliok "help" -varnish v1 -cliok "help -j" +varnish v1 -clijson "help -j" varnish v1 -clierr 106 "param.set waiter HASH(0x8839c4c)" diff --git a/include/vcli_serve.h b/include/vcli_serve.h index 7bc04c3da..8378993c4 100644 --- a/include/vcli_serve.h +++ b/include/vcli_serve.h @@ -85,7 +85,8 @@ int VCLI_Overflow(struct cli *cli); void VCLI_Out(struct cli *cli, const char *fmt, ...) v_printflike_(2, 3); void VCLI_Quote(struct cli *cli, const char *str); void VCLI_JSON_str(struct cli *cli, const char *str); -void VCLI_JSON_ver(struct cli *cli, unsigned ver, const char * const * av); +void VCLI_JSON_begin(struct cli *cli, unsigned ver, const char * const * av); +void VCLI_JSON_end(struct cli *cli); void VCLI_SetResult(struct cli *cli, unsigned r); typedef int cls_cb_f(void *priv); diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index 67c681642..5171d3173 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -159,26 +159,35 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv) cs = cli->cls; CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC); - VCLI_JSON_ver(cli, 1, av); + VCLI_JSON_begin(cli, 1, av); VTAILQ_FOREACH(clp, &cs->funcs, list) { if (clp->auth > cli->auth) continue; - VCLI_Out(cli, ",\n {"); - VCLI_Out(cli, "\n \"request\": "); + VCLI_Out(cli, ",\n {\n"); + VSB_indent(cli->sb, 2); + VCLI_Out(cli, "\"request\": "); VCLI_JSON_str(cli, clp->desc->request); - VCLI_Out(cli, ",\n \"syntax\": "); + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "\"syntax\": "); VCLI_JSON_str(cli, clp->desc->syntax); - VCLI_Out(cli, ",\n \"help\": "); + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "\"help\": "); VCLI_JSON_str(cli, clp->desc->help); - VCLI_Out(cli, ",\n \"minarg\": %d", clp->desc->minarg); - VCLI_Out(cli, ", \"maxarg\": %d", clp->desc->maxarg); - VCLI_Out(cli, ", \"flags\": "); + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "\"minarg\": %d", clp->desc->minarg); + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "\"maxarg\": %d", clp->desc->maxarg); + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "\"flags\": "); VCLI_JSON_str(cli, clp->flags); - VCLI_Out(cli, ", \"json\": %s", + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "\"json\": %s", clp->jsonfunc == NULL ? "false" : "true"); - VCLI_Out(cli, "\n }"); + VCLI_Out(cli, "\n"); + VSB_indent(cli->sb, -2); + VCLI_Out(cli, "}"); } - VCLI_Out(cli, "\n]\n"); + VCLI_JSON_end(cli); } /*-------------------------------------------------------------------- @@ -641,12 +650,14 @@ VCLI_JSON_str(struct cli *cli, const char *s) { CHECK_OBJ_NOTNULL(cli, CLI_MAGIC); + VSB_putc(cli->sb, '"'); VSB_quote(cli->sb, s, -1, VSB_QUOTE_JSON); + VSB_putc(cli->sb, '"'); } /*lint -e{818} cli could be const */ void -VCLI_JSON_ver(struct cli *cli, unsigned ver, const char * const * av) +VCLI_JSON_begin(struct cli *cli, unsigned ver, const char * const * av) { int i; @@ -658,6 +669,15 @@ VCLI_JSON_ver(struct cli *cli, unsigned ver, const char * const * av) VCLI_Out(cli, ", "); } VCLI_Out(cli, "]"); + VSB_indent(cli->sb, 2); +} + +void +VCLI_JSON_end(struct cli *cli) +{ + VSB_indent(cli->sb, -2); + VCLI_Out(cli, "\n"); + VCLI_Out(cli, "]\n"); } /*lint -e{818} cli could be const */ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:57 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:57 +0000 (UTC) Subject: [6.0] ab15cd458 sync std.fileread() docs with reality Message-ID: <20180816085257.E41D09B7EC@lists.varnish-cache.org> commit ab15cd458734dd64c616c158100da1c04439b251 Author: Nils Goroll Date: Mon May 14 09:18:42 2018 +0200 sync std.fileread() docs with reality The blind caching is OBE for six years now, see 344a709ccf9559f3d8e5d7a0a9a35c6e94705f0f diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index 34b6399aa..c8305ae9d 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -107,10 +107,8 @@ Example $Function STRING fileread(PRIV_CALL, STRING) Description - Reads a file and returns a string with the content. Please - note that it is not recommended to send variables to this - function the caching in the function doesn't take this into - account. Also, files are not re-read. + Reads a file and returns a string with the content. The result + is cached indefinitely per filename. Example synthetic("Response was served by " + std.fileread("/etc/hostname")); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] 25fcec646 change probe stats bitmaps to match %ju format Message-ID: <20180816085258.140D99B800@lists.varnish-cache.org> commit 25fcec646fd2e27bd5836c3ce583dab9389f0dfe Author: Nils Goroll Date: Mon May 14 11:37:23 2018 +0200 change probe stats bitmaps to match %ju format or should we use "%" PRIu64 in the format ? reported by Travis via @fgsch diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 478ad18f9..276391dba 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -72,7 +72,7 @@ struct vbp_target { unsigned good; /* Collected statistics */ -#define BITMAP(n, c, t, b) uint64_t n; +#define BITMAP(n, c, t, b) uintmax_t n; #include "tbl/backend_poll.h" double last; From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] 90dd989b0 Flexelintery Message-ID: <20180816085258.3B4609B813@lists.varnish-cache.org> commit 90dd989b09b077c08ec6960a11789c55fa9acdff Author: Poul-Henning Kamp Date: Mon May 14 11:38:44 2018 +0000 Flexelintery diff --git a/lib/libvcc/vsctool.py b/lib/libvcc/vsctool.py index 677703288..a665dff20 100644 --- a/lib/libvcc/vsctool.py +++ b/lib/libvcc/vsctool.py @@ -163,6 +163,7 @@ class vscset(object): fo = open(fon, "w") genhdr(fo, self.name) fo.write('#include "config.h"\n') + fo.write('#include \n') fo.write('#include \n') fo.write('#include "vdef.h"\n') fo.write('#include "vas.h"\n') diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c index 5fa883329..3603d73e5 100644 --- a/lib/libvmod_debug/vmod_debug_dyn.c +++ b/lib/libvmod_debug/vmod_debug_dyn.c @@ -38,7 +38,6 @@ #include #include "cache/cache.h" -#include "cache/cache_director.h" #include "vsa.h" #include "vcc_if.h" From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] f61d0e8e4 document purpose of doc/changes.rst as agreed upon at vdd18q2 Message-ID: <20180816085258.62F899B82C@lists.varnish-cache.org> commit f61d0e8e4f8756f3ddb15e062377a05cdd8cc69a Author: Nils Goroll Date: Mon May 14 19:52:37 2018 +0200 document purpose of doc/changes.rst as agreed upon at vdd18q2 Conflicts: doc/changes.rst diff --git a/doc/changes.rst b/doc/changes.rst index 9591ce872..dbc2e8600 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,3 +1,32 @@ +=================== +About this document +=================== + +.. keep this section at the top! + +This document contains notes from the Varnish developers about ongoing +development and past versions: + +* Developers will note here changes which they consider particularly + relevant or otherwise noteworthy + +* This document is not necessarily up-to-date with the code + +* It serves as a basis for release managers and others involved in + release documentation + +* It is not rendered as part of the official documentation and thus + only available in ReStructuredText (rst) format in the source + repository and -distribution. + +Official information about changes in releases and advise on the +upgrade process can be found in the ``doc/sphinx/whats-new/`` +directory, also available in HTML format at +http://varnish-cache.org/docs/trunk/whats-new/index.html and via +individual releases. These documents are updated as part of the +release process. + + ================================ Varnish Cache 6.0.1 (ongoing) ================================ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] 9f5a51a93 For HTTP/1.1 requests, Host is mandatory Message-ID: <20180816085258.8D6C19B841@lists.varnish-cache.org> commit 9f5a51a932d972b59858a1410a1fd6949ee6661a Author: Federico G. Schwindt Date: Tue May 1 15:51:28 2018 +0100 For HTTP/1.1 requests, Host is mandatory The check is added to the builtin logic for now. Fixes #2631. diff --git a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl index 4e74948da..a578a9c33 100644 --- a/bin/varnishd/builtin.vcl +++ b/bin/varnishd/builtin.vcl @@ -36,8 +36,14 @@ vcl 4.0; sub vcl_recv { if (req.method == "PRI") { - /* This will never happen in properly formed traffic (see: RFC7540) */ - return (synth(405)); + /* This will never happen in properly formed traffic (see: RFC7540) */ + return (synth(405)); + } + if (!req.http.host && + req.esi_level == 0 && + req.proto ~ "^(?i)HTTP/1.1") { + /* In HTTP/1.1, Host is required. */ + return (synth(400)); } if (req.method != "GET" && req.method != "HEAD" && diff --git a/bin/varnishtest/tests/r02633.vtc b/bin/varnishtest/tests/r02633.vtc new file mode 100644 index 000000000..3d15c3aa5 --- /dev/null +++ b/bin/varnishtest/tests/r02633.vtc @@ -0,0 +1,21 @@ +varnishtest "For HTTP/1.1 requests, Host is mandatory" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { +} -start + +client c1 { + txreq -proto HTTP/1.1 + rxresp + expect resp.status == 200 + txreq -proto HTTP/1.1 -nohost + rxresp + expect resp.status == 400 + txreq -proto HTTP/1.0 -nohost + rxresp + expect resp.status == 200 +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] f852f8774 ban lurker should back off on seeing a busy object Message-ID: <20180816085258.ABFC59B850@lists.varnish-cache.org> commit f852f8774bf2f87474c5264ae9251fd29fca2911 Author: Nils Goroll Date: Thu May 17 17:40:53 2018 +0200 ban lurker should back off on seeing a busy object HSH_Unbusy() calls BAN_NewObjCore() not holding the objhead lock, so the ban lurker may race and grab the ban mtx just after the new oc has been inserted, but the busy flag not yet cleared. While it would be correct to call BAN_NewObjCore() with the objhead mtx held, doing so would increase the pressure on the combined ban & objhead mtx. If the ban lurker encounters a busy object, we know that there must be an unbusy in progress and it would be wiser to rather back off in favor of the it. Fixes #2681 diff --git a/bin/varnishd/cache/cache_ban_lurker.c b/bin/varnishd/cache/cache_ban_lurker.c index 52a3c79d4..f59b888ce 100644 --- a/bin/varnishd/cache/cache_ban_lurker.c +++ b/bin/varnishd/cache/cache_ban_lurker.c @@ -167,7 +167,7 @@ ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt) oh = oc->objhead; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); if (!Lck_Trylock(&oh->mtx)) { - if (oc->refcnt == 0) { + if (oc->refcnt == 0 || oc->flags & OC_F_BUSY) { Lck_Unlock(&oh->mtx); } else { /* From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] 18f8a2480 detail fetch processor state in panics Message-ID: <20180816085258.CF7989B86B@lists.varnish-cache.org> commit 18f8a24809ca0160493dff4ef14f8d95e7b633db Author: Nils Goroll Date: Fri May 18 14:33:20 2018 +0200 detail fetch processor state in panics Ref #2683 diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index dea26a630..1dc3d1f32 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -355,9 +355,44 @@ pan_wrk(struct vsb *vsb, const struct worker *wrk) } static void -pan_busyobj(struct vsb *vsb, const struct busyobj *bo) +pan_vfp(struct vsb *vsb, const struct vfp_ctx *vfc) { struct vfp_entry *vfe; + + VSB_printf(vsb, "vfc = %p {\n", vfc); + VSB_indent(vsb, 2); + VSB_printf(vsb, "failed = %d,\n", vfc->failed); + VSB_printf(vsb, "req = %p,\n", vfc->req); + VSB_printf(vsb, "resp = %p,\n", vfc->resp); + VSB_printf(vsb, "wrk = %p,\n", vfc->wrk); + VSB_printf(vsb, "oc = %p,\n", vfc->oc); + + if (!VTAILQ_EMPTY(&vfc->vfp)) { + VSB_printf(vsb, "filters = {\n"); + VSB_indent(vsb, 2); + VTAILQ_FOREACH(vfe, &vfc->vfp, list) { + VSB_printf(vsb, "%s = %p {\n", + vfe->vfp->name, vfe); + VSB_indent(vsb, 2); + VSB_printf(vsb, "priv1 = %p,\n", vfe->priv1); + VSB_printf(vsb, "priv2 = %zd,\n", vfe->priv2); + VSB_printf(vsb, "closed = %d\n", vfe->closed); + VSB_indent(vsb, -2); + VSB_printf(vsb, "},\n"); + } + VSB_indent(vsb, -2); + VSB_printf(vsb, "},\n"); + } + + VSB_printf(vsb, "obj_flags = 0x%x,\n", vfc->obj_flags); + VSB_indent(vsb, -2); + VSB_printf(vsb, "},\n"); +}; + + +static void +pan_busyobj(struct vsb *vsb, const struct busyobj *bo) +{ const char *p; VSB_printf(vsb, "busyobj = %p {\n", bo); @@ -380,13 +415,8 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo) if (VALID_OBJ(bo->htc, HTTP_CONN_MAGIC)) pan_htc(vsb, bo->htc); - if (!VTAILQ_EMPTY(&bo->vfc->vfp)) { - VSB_printf(vsb, "filters ="); - VTAILQ_FOREACH(vfe, &bo->vfc->vfp, list) - VSB_printf(vsb, " %s=%d", - vfe->vfp->name, (int)vfe->closed); - VSB_printf(vsb, "\n"); - } + if (bo->vfc) + pan_vfp(vsb, bo->vfc); VDI_Panic(bo->director_req, vsb, "director_req"); if (bo->director_resp == bo->director_req) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:58 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:58 +0000 (UTC) Subject: [6.0] 85ce04463 Fix cache_req_body handling for H/2 requests Message-ID: <20180816085259.006D29B878@lists.varnish-cache.org> commit 85ce04463277f75647caa5b1a0d7b5c3dc7d3606 Author: Dag Haavi Finstad Date: Fri May 18 14:35:40 2018 +0200 Fix cache_req_body handling for H/2 requests The h/2 request body VFP would drop data when the input buffer was too small to fit the data in the received frame. With this fix we have the VFP code call us again with a fresh buffer when we run out. Fixes: #2679 diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 6a0c92be5..1da101a0e 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -770,6 +770,12 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) h2->rxf_len -= l; } *lp = l; + if (h2->rxf_len > 0) { + /* We ran out of storage: Have VFP call us + * again with a fresh buffer */ + Lck_Unlock(&h2->sess->mtx); + return (VFP_OK); + } if (h2->rxf_len == 0) { if (h2->rxf_flags & H2FF_DATA_END_STREAM) retval = VFP_END; diff --git a/bin/varnishtest/tests/r02679.vtc b/bin/varnishtest/tests/r02679.vtc new file mode 100644 index 000000000..296ce9c29 --- /dev/null +++ b/bin/varnishtest/tests/r02679.vtc @@ -0,0 +1,31 @@ +varnishtest "#2679: H/2 rxbody vfp drops data" + +server s1 { + rxreq + expect req.http.content-length == "31469" + expect req.bodylen == 31469 + txresp +} -start + +varnish v1 -vcl+backend { + import std; + sub vcl_recv { +# std.cache_req_body(100KB); + } +} -start + +varnish v1 -cliok "param.set feature +http2" + +client c1 { + stream 1 { + txreq -req POST -hdr "content-length" "31469" -nostrend + txdata -datalen 1550 -nostrend + rxwinup + txdata -datalen 16000 -nostrend + rxwinup + txdata -datalen 13919 + rxwinup + rxresp + expect resp.status == 200 + } -run +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:59 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:59 +0000 (UTC) Subject: [6.0] e8863a974 Fix screwup in previous commit Message-ID: <20180816085259.24FEE9B88A@lists.varnish-cache.org> commit e8863a9740e0434f918fb9d3fb1a0afd00f77cf3 Author: Dag Haavi Finstad Date: Fri May 18 14:45:25 2018 +0200 Fix screwup in previous commit diff --git a/bin/varnishtest/tests/r02679.vtc b/bin/varnishtest/tests/r02679.vtc index 296ce9c29..ca99d75e8 100644 --- a/bin/varnishtest/tests/r02679.vtc +++ b/bin/varnishtest/tests/r02679.vtc @@ -10,7 +10,7 @@ server s1 { varnish v1 -vcl+backend { import std; sub vcl_recv { -# std.cache_req_body(100KB); + std.cache_req_body(100KB); } } -start From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:59 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:59 +0000 (UTC) Subject: [6.0] 56b1abda2 fix layer 8 brace overflow error Message-ID: <20180816085259.46FC29B89A@lists.varnish-cache.org> commit 56b1abda2bbaa7824b83c6f34daa88fe22dd9c60 Author: Nils Goroll Date: Fri May 18 14:48:35 2018 +0200 fix layer 8 brace overflow error diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 1dc3d1f32..0666c89e7 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -387,7 +387,7 @@ pan_vfp(struct vsb *vsb, const struct vfp_ctx *vfc) VSB_printf(vsb, "obj_flags = 0x%x,\n", vfc->obj_flags); VSB_indent(vsb, -2); VSB_printf(vsb, "},\n"); -}; +} static void From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:59 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:59 +0000 (UTC) Subject: [6.0] 78513e985 gc duplicate statement with no effect Message-ID: <20180816085259.827409B8AB@lists.varnish-cache.org> commit 78513e9850f13a06987d551ed37b75eea2fda646 Author: Nils Goroll Date: Fri May 18 14:58:27 2018 +0200 gc duplicate statement with no effect diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c index 3694c0ad2..d5d256d56 100644 --- a/bin/varnishd/cache/cache_gzip.c +++ b/bin/varnishd/cache/cache_gzip.c @@ -620,7 +620,6 @@ vfp_testgunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); AN(p); AN(lp); - CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); vp = VFP_Suck(vc, p, lp); if (vp == VFP_ERROR) return (vp); From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:59 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:59 +0000 (UTC) Subject: [6.0] af9b90845 Multiple -[IX] options may be given to VUTs Message-ID: <20180816085259.A764F9B8BD@lists.varnish-cache.org> commit af9b90845520a1670b6f10caf0ac0731ee6be441 Author: Dridi Boukelmoune Date: Mon May 21 12:48:05 2018 +0200 Multiple -[IX] options may be given to VUTs diff --git a/include/vapi/vapi_options.h b/include/vapi/vapi_options.h index 98b838bbf..3d95c3123 100644 --- a/include/vapi/vapi_options.h +++ b/include/vapi/vapi_options.h @@ -63,7 +63,7 @@ VOPT("I:", "[-I <[taglist:]regex>]", "Include by regex", \ "Include by regex matching. Output only records matching" \ " taglist and regular expression. Applies to any tag if" \ - " taglist is absent.\n" \ + " taglist is absent. Multiple -I options may be given.\n" \ "\n" \ VSL_iI_PS \ ) @@ -104,5 +104,5 @@ VOPT("X:", "[-X <[taglist:]regex>]", "Exclude by regex", \ "Exclude by regex matching. Do not output records matching" \ " taglist and regular expression. Applies to any tag if" \ - " taglist is absent." \ + " taglist is absent. Multiple -X options may be given.\n" \ ) From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:59 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:59 +0000 (UTC) Subject: [6.0] 79c9415f3 Introduction of '-' CLI prefix allowed empty commands to sneak through. Message-ID: <20180816085259.D914A9B8D1@lists.varnish-cache.org> commit 79c9415f3dc049e6d8d0a7aa410c0ae616724599 Author: Poul-Henning Kamp Date: Tue May 22 13:09:31 2018 +0000 Introduction of '-' CLI prefix allowed empty commands to sneak through. Fixes #2647 diff --git a/bin/varnishtest/tests/r02647.vtc b/bin/varnishtest/tests/r02647.vtc new file mode 100644 index 000000000..09c63cee4 --- /dev/null +++ b/bin/varnishtest/tests/r02647.vtc @@ -0,0 +1,15 @@ +varnishtest "empty cli command" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend {} -start + +varnish v1 -clierr 100 "-" + +client c1 { + txreq + rxresp +} -run diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index 5171d3173..b1084a162 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -278,6 +278,12 @@ cls_exec(struct VCLS_fd *cfd, char * const *av) break; } + if (av[1] == NULL) { + VCLI_Out(cli, "Empty CLI command.\n"); + VCLI_SetResult(cli, CLIS_SYNTAX); + break; + } + if (isupper(av[1][0])) { VCLI_Out(cli, "all commands are in lower-case.\n"); VCLI_SetResult(cli, CLIS_UNKNOWN); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:00 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:00 +0000 (UTC) Subject: [6.0] e7fc65428 Handle string literal concatenation correctly. Message-ID: <20180816085300.1F2469B8F5@lists.varnish-cache.org> commit e7fc65428051b5259a8ce3e974954b86791ae4af Author: Poul-Henning Kamp Date: Tue May 22 14:27:13 2018 +0000 Handle string literal concatenation correctly. Fixes #2685 diff --git a/bin/varnishtest/tests/c00068.vtc b/bin/varnishtest/tests/c00068.vtc index 88a47b631..5fb3b48f9 100644 --- a/bin/varnishtest/tests/c00068.vtc +++ b/bin/varnishtest/tests/c00068.vtc @@ -10,6 +10,8 @@ server s1 { } -start varnish v1 -vcl+backend { + import std; + sub vcl_backend_response { if (bereq.url == "/333") { set beresp.status = 333; @@ -18,7 +20,7 @@ varnish v1 -vcl+backend { } sub vcl_deliver { if (req.url == "/332") { - return (synth(332, "FOO")); + return (synth(332, "F" + "OO" + std.tolower("FOO"))); } else if (req.url == "/333") { return (synth(resp.status + 1000, resp.reason)); @@ -64,6 +66,7 @@ client c2 { txreq -url /332 rxresp expect resp.status == 332 + expect resp.reason == "FOOfoo" expect resp.http.restarts == 1 expect resp.bodylen == 1 } -run diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 37bfb04ed..e5ef67416 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -920,6 +920,7 @@ vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt) *e = vcc_expr_edit(tl, STRINGS, "\v1\n\v2", *e, e2); (*e)->constant = EXPR_CONST; + (*e)->nstr = 1; if (lit) (*e)->constant |= EXPR_STR_CONST; } else { @@ -1297,6 +1298,8 @@ vcc_Expr(struct vcc *tl, vcc_type_t fmt) assert(fmt != STRINGS); vcc_expr0(tl, &e, fmt); ERRCHK(tl); + assert(e->fmt == fmt); + vcc_expr_fmt(tl->fb, tl->indent, e); VSB_printf(tl->fb, "\n"); vcc_delete_expr(e); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:00 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:00 +0000 (UTC) Subject: [6.0] 108f44dae document probe window bits Message-ID: <20180816085300.45CEB9B903@lists.varnish-cache.org> commit 108f44dae6b5e8cbb930025b39798c99e30536b0 Author: Nils Goroll Date: Tue May 22 23:07:03 2018 +0200 document probe window bits See comment on how we could auto-generate the documentation from the include - any less hackish ideas welcome diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index 89a422a5c..fa348b39f 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -370,6 +370,20 @@ SLTM(Hash, SLT_F_UNSAFE, "Value added to hash", NODEF_NOTICE ) +/* + * Probe window bits: + * + * the documentation below could get auto-generated like so: + * + * ( echo '#define PROBE_BITS_DOC \' ; \ + * $CC -D 'BITMAP(n, c, t, b)="\t" #c ": " t "\n" \' \ + * -E ./include/tbl/backend_poll.h | grep -E '^"' ; \ + * echo '""' ) >./include/tbl/backend_poll_doc.h + * + * as this has a hackish feel to it, the documentation is included here as text + * until we find a better solution or the above is accepted + */ + SLTM(Backend_health, 0, "Backend health check", "The result of a backend health probe.\n\n" "The format is::\n\n" @@ -385,6 +399,17 @@ SLTM(Backend_health, 0, "Backend health check", "\t| +---------------------- Status message\n" "\t+------------------------- Backend name\n" "\n" + + "Probe window bits are::\n\n" + "\t" "'4'" ": " "Good IPv4" "\n" + "\t" "'6'" ": " "Good IPv6" "\n" + "\t" "'U'" ": " "Good UNIX" "\n" + "\t" "'x'" ": " "Error Xmit" "\n" + "\t" "'X'" ": " "Good Xmit" "\n" + "\t" "'r'" ": " "Error Recv" "\n" + "\t" "'R'" ": " "Good Recv" "\n" + "\t" "'H'" ": " "Happy" "\n" + "\n" ) SLTM(VCL_Log, 0, "Log statement from VCL", From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:00 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:00 +0000 (UTC) Subject: [6.0] e80b33f89 Reject headers without name Message-ID: <20180816085300.6F0B19B90F@lists.varnish-cache.org> commit e80b33f895fe50bf67f93e9c3ddbd00ff5b5eed6 Author: Federico G. Schwindt Date: Wed May 23 01:54:20 2018 +0100 Reject headers without name diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index b3fbde72f..ad4421844 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -155,16 +155,16 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, *q++ = ' '; } + /* Empty header = end of headers */ + if (p == q) + break; + if (q - p > maxhdr) { VSLb(hp->vsl, SLT_BogoHeader, "Header too long: %.*s", (int)(q - p > 20 ? 20 : q - p), p); return (400); } - /* Empty header = end of headers */ - if (p == q) - break; - if (vct_islws(*p)) { VSLb(hp->vsl, SLT_BogoHeader, "1st header has white space: %.*s", @@ -172,6 +172,13 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, return (400); } + if (*p == ':') { + VSLb(hp->vsl, SLT_BogoHeader, + "Missing header name: %.*s", + (int)(q - p > 20 ? 20 : q - p), p); + return (400); + } + if ((p[0] == 'i' || p[0] == 'I') && (p[1] == 'f' || p[1] == 'F') && p[2] == '-') diff --git a/bin/varnishtest/tests/b00040.vtc b/bin/varnishtest/tests/b00040.vtc index 8d5db1525..cc7479d05 100644 --- a/bin/varnishtest/tests/b00040.vtc +++ b/bin/varnishtest/tests/b00040.vtc @@ -2,7 +2,7 @@ varnishtest "test certain mailformed requests" server s1 { rxreq - # expect req.url == /3 + expect req.url == /4 txresp } -start @@ -15,6 +15,7 @@ logexpect l1 -v v1 -g raw { expect * 1010 BogoHeader {Header has ctrl char 0x01} expect * 1012 BogoHeader {Header has ctrl char 0x0d} expect * 1014 BogoHeader {Header has ctrl char 0x0d} + expect * 1016 BogoHeader {Missing header name:.*} } -start client c1 { @@ -71,6 +72,13 @@ client c1 { rxresp expect resp.status == 400 } -run +delay .1 + +client c1 { + send "GET /8 HTTP/1.1\r\nHost: foo\r\n: Header\r\n\r\n" + rxresp + expect resp.status == 400 +} -run logexpect l1 -wait From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:00 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:00 +0000 (UTC) Subject: [6.0] 270cc2b4a Correctly identify these as non-separators Message-ID: <20180816085300.91AE79B927@lists.varnish-cache.org> commit 270cc2b4a485ec8add5ecc02c37da337533ec6c7 Author: Federico G. Schwindt Date: Wed May 23 01:55:15 2018 +0100 Correctly identify these as non-separators diff --git a/lib/libvarnish/vct.c b/lib/libvarnish/vct.c index 8d36b102c..73b784e32 100644 --- a/lib/libvarnish/vct.c +++ b/lib/libvarnish/vct.c @@ -54,7 +54,7 @@ const uint16_t vct_typtab[256] = { [0x06] = VCT_CTL, [0x07] = VCT_CTL, [0x08] = VCT_CTL, - [0x09] = VCT_CTL | VCT_SP | VCT_SEPARATOR, + [0x09] = VCT_CTL | VCT_SP, [0x0a] = VCT_CTL | VCT_CRLF, [0x0b] = VCT_CTL | VCT_VT, [0x0c] = VCT_CTL, @@ -77,7 +77,7 @@ const uint16_t vct_typtab[256] = { [0x1d] = VCT_CTL, [0x1e] = VCT_CTL, [0x1f] = VCT_CTL, - [0x20] = VCT_SP | VCT_SEPARATOR, + [0x20] = VCT_SP, [0x21] = VCT_TCHAR, [0x22] = VCT_SEPARATOR, [0x23] = VCT_TCHAR, From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:00 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:00 +0000 (UTC) Subject: [6.0] f39c63936 Try to speed things up and misc cleanup Message-ID: <20180816085300.B7D519B937@lists.varnish-cache.org> commit f39c63936aeee8ced537ab9206d06e14b230fb6f Author: Federico G. Schwindt Date: Wed May 23 10:49:51 2018 +0100 Try to speed things up and misc cleanup diff --git a/.travis.yml b/.travis.yml index 2cae8dbee..88a234630 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ --- -sudo: required language: c +sudo: false matrix: fast_finish: true include: @@ -14,6 +14,7 @@ matrix: dist: trusty compiler: clang env: CLANG=6.0 SAN_FLAGS="--enable-asan --enable-ubsan" + sudo: required - os: osx osx_image: xcode9.3 compiler: clang @@ -32,33 +33,38 @@ notifications: on_success: change use_notice: true before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update; - brew upgrade python; - brew install docutils sphinx-doc nghttp2; - fi - - if [[ -n "$CLANG" ]]; then + - | + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + brew update + brew upgrade python + brew install docutils sphinx-doc nghttp2 + elif [[ -n "$CLANG" ]]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | - sudo apt-key add -; + sudo apt-key add - sudo apt-add-repository -y - "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-$CLANG main"; - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA9EF27F; + "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-$CLANG main" + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA9EF27F sudo apt-add-repository -y - "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main"; - sudo apt-get update; - sudo apt-get install -y clang-$CLANG llvm-$CLANG; - export CC=clang-$CLANG; - export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage ${SAN_FLAGS}"; - export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0,disable_coredump=0; - export LSAN_OPTIONS=abort_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/lsan.suppr; - export TSAN_OPTIONS=abort_on_error=1,halt_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/tsan.suppr; - export UBSAN_OPTIONS=halt_on_error=1,print_stacktrace=1,use_sigaltstack=0,suppressions=$(pwd)/tools/ubsan.suppr; + "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main" + sudo apt-get update + sudo apt-get install -y clang-$CLANG llvm-$CLANG + export CC=clang-$CLANG + export CONFIGURE_ARGS="--enable-developer-warnings --enable-debugging-symbols --disable-stack-protector --with-persistent-storage ${SAN_FLAGS}" + export ASAN_OPTIONS=abort_on_error=1,detect_odr_violation=1,detect_leaks=1,detect_stack_use_after_return=1,detect_invalid_pointer_pairs=1,handle_segv=0,handle_sigbus=0,use_sigaltstack=0,disable_coredump=0 + export LSAN_OPTIONS=abort_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/lsan.suppr + export TSAN_OPTIONS=abort_on_error=1,halt_on_error=1,use_sigaltstack=0,suppressions=$(pwd)/tools/tsan.suppr + export UBSAN_OPTIONS=halt_on_error=1,print_stacktrace=1,use_sigaltstack=0,suppressions=$(pwd)/tools/ubsan.suppr fi - ./autogen.sh - ./configure ${CONFIGURE_ARGS} script: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - export PYTHONPATH=`brew --prefix`/lib/python2.7/site-packages; - export PATH="/usr/local/opt/sphinx-doc/bin:$PATH"; fi - - if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then make -j3 distcheck; fi - - if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then make -j3 check VERBOSE=1; fi + - | + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + export PYTHONPATH=`brew --prefix`/lib/python2.7/site-packages + export PATH="/usr/local/opt/sphinx-doc/bin:$PATH" + fi + if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then + make -j3 distcheck + else + make -j3 check VERBOSE=1 + fi From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:00 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:00 +0000 (UTC) Subject: [6.0] 0740ab714 We need line continuation now Message-ID: <20180816085300.DDDAA9B94D@lists.varnish-cache.org> commit 0740ab7140300a0263fcf9804e801e233cc6d7bb Author: Federico G. Schwindt Date: Wed May 23 13:04:22 2018 +0100 We need line continuation now diff --git a/.travis.yml b/.travis.yml index 88a234630..021ed0de5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,12 +39,11 @@ before_install: brew upgrade python brew install docutils sphinx-doc nghttp2 elif [[ -n "$CLANG" ]]; then - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | - sudo apt-key add - - sudo apt-add-repository -y + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo apt-add-repository -y \ "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-$CLANG main" sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA9EF27F - sudo apt-add-repository -y + sudo apt-add-repository -y \ "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main" sudo apt-get update sudo apt-get install -y clang-$CLANG llvm-$CLANG From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:01 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:01 +0000 (UTC) Subject: [6.0] 17eb66323 Silence a Coverity non-defect Message-ID: <20180816085301.128829B965@lists.varnish-cache.org> commit 17eb66323a702a85b56a59786cb1039e1491e1f2 Author: Dag Haavi Finstad Date: Thu May 24 10:06:34 2018 +0200 Silence a Coverity non-defect diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 0666c89e7..cf22c0ea7 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -401,6 +401,7 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo) VSB_indent(vsb, 2); PAN_CheckMagic(vsb, bo, BUSYOBJ_MAGIC); pan_ws(vsb, bo->ws); + AN(bo->vfc); VSB_printf(vsb, "retries = %d, ", bo->retries); VSB_printf(vsb, "failed = %d, ", bo->vfc->failed); VSB_printf(vsb, "flags = {"); @@ -415,8 +416,7 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo) if (VALID_OBJ(bo->htc, HTTP_CONN_MAGIC)) pan_htc(vsb, bo->htc); - if (bo->vfc) - pan_vfp(vsb, bo->vfc); + pan_vfp(vsb, bo->vfc); VDI_Panic(bo->director_req, vsb, "director_req"); if (bo->director_resp == bo->director_req) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:01 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:01 +0000 (UTC) Subject: [6.0] b95646d8b In panic code, handle NULL pointers with grace Message-ID: <20180816085301.3B0DB9B97A@lists.varnish-cache.org> commit b95646d8bd2e305365d3c67d13e461999e4bc3ef Author: Nils Goroll Date: Thu May 24 11:10:12 2018 +0200 In panic code, handle NULL pointers with grace We do not want to cause a panic from the panic handler. It could be argued that bo->vfc cannot possibly be NULL, except when it is - and that's what we got the panic handler for. vfc->failed is output by pan_vfp now so I should have removed that duplication when introducing pan_vfp diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index cf22c0ea7..8282ed814 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -401,9 +401,7 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo) VSB_indent(vsb, 2); PAN_CheckMagic(vsb, bo, BUSYOBJ_MAGIC); pan_ws(vsb, bo->ws); - AN(bo->vfc); VSB_printf(vsb, "retries = %d, ", bo->retries); - VSB_printf(vsb, "failed = %d, ", bo->vfc->failed); VSB_printf(vsb, "flags = {"); p = ""; /*lint -save -esym(438,p) -e539 */ @@ -416,7 +414,8 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo) if (VALID_OBJ(bo->htc, HTTP_CONN_MAGIC)) pan_htc(vsb, bo->htc); - pan_vfp(vsb, bo->vfc); + if (bo->vfc) + pan_vfp(vsb, bo->vfc); VDI_Panic(bo->director_req, vsb, "director_req"); if (bo->director_resp == bo->director_req) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:01 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:01 +0000 (UTC) Subject: [6.0] 79245225c Plug a leak of the read end of VSUB pipes Message-ID: <20180816085301.6395B9B98F@lists.varnish-cache.org> commit 79245225cf0eed52a06425962d1d302086756e08 Author: Dridi Boukelmoune Date: Fri May 25 13:28:04 2018 +0200 Plug a leak of the read end of VSUB pipes diff --git a/lib/libvarnish/vsub.c b/lib/libvarnish/vsub.c index 2792ebc19..cafbe4086 100644 --- a/lib/libvarnish/vsub.c +++ b/lib/libvarnish/vsub.c @@ -127,6 +127,7 @@ VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const char *name, } closefd(&p[1]); (void)VLU_File(p[0], vsub_vlu, &sp, 0); + closefd(&p[0]); if (sp.maxlines >= 0 && sp.lines > sp.maxlines) VSB_printf(sb, "[%d lines truncated]\n", sp.lines - sp.maxlines); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:01 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:01 +0000 (UTC) Subject: [6.0] 941e00db3 Various Flexelinting Message-ID: <20180816085301.882039B99D@lists.varnish-cache.org> commit 941e00db3c120ed5fa0e6635b80a76d8bb9304f1 Author: Poul-Henning Kamp Date: Sun May 27 07:08:49 2018 +0000 Various Flexelinting diff --git a/bin/varnishhist/flint.lnt b/bin/varnishhist/flint.lnt index a4289bf2c..1342b8e4e 100644 --- a/bin/varnishhist/flint.lnt +++ b/bin/varnishhist/flint.lnt @@ -1,3 +1,4 @@ -efile(451, "varnishhist_profiles.h") -efile(451, "varnishhist_options.h") -sem(usage, r_no) +-sem(profile_error, r_no) diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 5d32d6a80..6c72a655a 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -63,7 +63,7 @@ static struct VUT *vut; static int hist_low; static int hist_high; static int hist_range; -static int hist_buckets; +static unsigned hist_buckets; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; @@ -143,7 +143,7 @@ update(void) unsigned bm[n], bh[n]; unsigned max; unsigned i, j, scale; - int k, l; + unsigned k, l; erase(); @@ -161,10 +161,11 @@ update(void) mvprintw(0, 0, "%*s", COLS - 1, ident); /* count our flock */ - for (i = 0; i < n; ++i) - bm[i] = bh[i] = 0; + memset(bm, 0, sizeof bm); + memset(bh, 0, sizeof bh); for (k = 0, max = 1; k < hist_buckets; ++k) { l = k * n / hist_buckets; + assert(l < n); bm[l] += bucket_miss[k]; bh[l] += bucket_hit[k]; if (bm[l] + bh[l] > max) @@ -413,13 +414,13 @@ do_curses(void *arg) break; case '\032': /* Ctrl-Z */ endwin(); - raise(SIGTSTP); + AZ(raise(SIGTSTP)); break; case '\003': /* Ctrl-C */ case '\021': /* Ctrl-Q */ case 'Q': case 'q': - raise(SIGINT); + AZ(raise(SIGINT)); endwin(); return (NULL); case '0': @@ -432,7 +433,7 @@ do_curses(void *arg) case '7': case '8': case '9': - delay = 1 << (ch - '0'); + delay = 1U << (ch - '0'); break; case '+': delay /= 2; @@ -483,7 +484,7 @@ usage(int status) exit(status); } -static void +static void v_noreturn_ profile_error(const char *s) { fprintf(stderr, "-P: '%s' is not a valid" @@ -506,7 +507,7 @@ main(int argc, char **argv) char *colon; const char *ptag, *profile = "responsetime"; pthread_t thr; - int fnum = -1; + int fnum; struct profile cli_p = {0}; vut = VUT_InitProg(argc, argv, &vopt_spec); diff --git a/lib/libvarnishapi/vsl_dispatch.c b/lib/libvarnishapi/vsl_dispatch.c index 5c1a5347e..6e786d4f7 100644 --- a/lib/libvarnishapi/vsl_dispatch.c +++ b/lib/libvarnishapi/vsl_dispatch.c @@ -582,7 +582,6 @@ vtx_retire(struct VSLQ *vslq, struct vtx **pvtx) vslq->n_cache++; } else { FREE_OBJ(vtx); - vtx = NULL; } } @@ -693,7 +692,7 @@ vtx_parse_link(const char *str, enum VSL_transaction_e *ptype, return (0); /* transaction type */ - for (et = 0; et < VSL_t__MAX; et++) + for (et = VSL_t_unknown; et < VSL_t__MAX; et++) if (!strcmp(type, vsl_t_names[et])) break; if (et >= VSL_t__MAX) @@ -709,7 +708,7 @@ vtx_parse_link(const char *str, enum VSL_transaction_e *ptype, return (2); /* transaction reason */ - for (er = 0; er < VSL_r__MAX; er++) + for (er = VSL_r_unknown; er < VSL_r__MAX; er++) if (!strcmp(reason, vsl_r_names[er])) break; if (er >= VSL_r__MAX) diff --git a/lib/libvmod_blob/flint.lnt b/lib/libvmod_blob/flint.lnt index 1b6f0888f..016a8329d 100644 --- a/lib/libvmod_blob/flint.lnt +++ b/lib/libvmod_blob/flint.lnt @@ -1 +1,4 @@ -efile(451, "tbl_*.h") // No include guard + +-e784 // Nul character truncated from string + From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:01 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:01 +0000 (UTC) Subject: [6.0] 20913576f Use poll(2) instead of select(2) to be consistent with the rest of the source tree. Message-ID: <20180816085301.AAA0F9B9BB@lists.varnish-cache.org> commit 20913576f908f136ee7839d295ee8fb2a3e3069b Author: Poul-Henning Kamp Date: Sun May 27 10:17:47 2018 +0000 Use poll(2) instead of select(2) to be consistent with the rest of the source tree. diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c index 116efdd02..3f0f69065 100644 --- a/bin/varnishtest/vtc_barrier.c +++ b/bin/varnishtest/vtc_barrier.c @@ -29,6 +29,7 @@ #include "config.h" #include +#include #include #include #include @@ -125,11 +126,10 @@ barrier_sock_thread(void *priv) { struct barrier *b; struct vtclog *vl; - struct timeval tmo; const char *err; char abuf[16], pbuf[6]; int i, sock, *conns; - fd_set rfds; + struct pollfd pfd[1]; CAST_OBJ_NOTNULL(b, priv, BARRIER_MAGIC); assert(b->type == BARRIER_SOCK); @@ -161,12 +161,10 @@ barrier_sock_thread(void *priv) AN(conns); while (b->active) { - FD_ZERO(&rfds); - FD_SET(sock, &rfds); + pfd[0].fd = sock; + pfd[0].events = POLLIN; - tmo.tv_sec = 1; - tmo.tv_usec = 0; - i = select(sock + 1, &rfds, NULL, NULL, &tmo); + i = poll(pfd, 1, 1000); if (i == 0) continue; if (i < 0) { @@ -219,7 +217,8 @@ barrier_sock_thread(void *priv) macro_undef(vl, b->name, "sock"); closefd(&sock); free(conns); - pthread_cleanup_pop(1); + pthread_cleanup_pop(0); + vtc_logclose(vl); return (NULL); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:01 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:01 +0000 (UTC) Subject: [6.0] 56c70c2a0 Flexelinting Message-ID: <20180816085301.D17FA9B9D2@lists.varnish-cache.org> commit 56c70c2a0f9bc9f35143c4052be972211cc5fd7d Author: Poul-Henning Kamp Date: Sun May 27 10:18:16 2018 +0000 Flexelinting Use pthread_cleanup_pop(0) and an explict call to the cleanup function to make things visible to FlexeLint. diff --git a/bin/varnishtest/hpack.h b/bin/varnishtest/hpack.h index 9df6785ca..94b734715 100644 --- a/bin/varnishtest/hpack.h +++ b/bin/varnishtest/hpack.h @@ -33,7 +33,7 @@ struct hpk_iter; struct hpk_ctx * HPK_NewCtx(uint32_t tblsize); void HPK_FreeCtx(struct hpk_ctx *ctx); -struct hpk_iter * HPK_NewIter(struct hpk_ctx *ctx, char *buf, int size); +struct hpk_iter * HPK_NewIter(struct hpk_ctx *ctx, void *buf, int size); void HPK_FreeIter(struct hpk_iter *iter); enum hpk_result HPK_DecHdr(struct hpk_iter *iter, struct hpk_hdr *header); diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index 4b2f608fc..d2f72b955 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -237,7 +237,8 @@ client_thread(void *priv) } vtc_log(vl, 2, "Ending"); VSB_destroy(&vsb); - pthread_cleanup_pop(1); + pthread_cleanup_pop(0); + vtc_logclose(vl); return (NULL); } diff --git a/bin/varnishtest/vtc_h2_hpack.c b/bin/varnishtest/vtc_h2_hpack.c index 403db13a8..52c8ee9cc 100644 --- a/bin/varnishtest/vtc_h2_hpack.c +++ b/bin/varnishtest/vtc_h2_hpack.c @@ -26,6 +26,7 @@ * SUCH DAMAGE. */ +#include #include #include #include @@ -34,6 +35,7 @@ #include "vdef.h" #include "vas.h" +#include "vqueue.h" #include "hpack.h" #include "vtc_h2_priv.h" diff --git a/bin/varnishtest/vtc_h2_priv.h b/bin/varnishtest/vtc_h2_priv.h index 796e94049..5c646d3ed 100644 --- a/bin/varnishtest/vtc_h2_priv.h +++ b/bin/varnishtest/vtc_h2_priv.h @@ -26,22 +26,20 @@ * SUCH DAMAGE. */ -#include "vqueue.h" - #define ITER_DONE(iter) (iter->buf == iter->end ? hpk_done : hpk_more) struct dynhdr { - struct hpk_hdr header; - VTAILQ_ENTRY(dynhdr) list; + struct hpk_hdr header; + VTAILQ_ENTRY(dynhdr) list; }; VTAILQ_HEAD(dynamic_table,dynhdr); struct hpk_iter { - struct hpk_ctx *ctx; - char *orig; - char *buf; - char *end; + struct hpk_ctx *ctx; + uint8_t *orig; + uint8_t *buf; + uint8_t *end; }; const struct txt * tbl_get_key(const struct hpk_ctx *ctx, uint32_t index); diff --git a/bin/varnishtest/vtc_h2_tbl.c b/bin/varnishtest/vtc_h2_tbl.c index c0262afc7..0aaa35289 100644 --- a/bin/varnishtest/vtc_h2_tbl.c +++ b/bin/varnishtest/vtc_h2_tbl.c @@ -26,14 +26,15 @@ * SUCH DAMAGE. */ +#include +#include #include #include -#include -#include #include "vdef.h" #include "vas.h" +#include "vqueue.h" #include "hpack.h" #include "vtc_h2_priv.h" @@ -77,7 +78,7 @@ struct hpk_ctx { struct hpk_iter * -HPK_NewIter(struct hpk_ctx *ctx, char *buf, int size) +HPK_NewIter(struct hpk_ctx *ctx, void *buf, int size) { struct hpk_iter *iter = malloc(sizeof(*iter)); assert(iter); @@ -87,7 +88,7 @@ HPK_NewIter(struct hpk_ctx *ctx, char *buf, int size) iter->ctx = ctx; iter->orig = buf; iter->buf = buf; - iter->end = buf + size; + iter->end = iter->buf + size; return (iter); } diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index edfe79653..54b2a2097 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -1924,7 +1924,8 @@ http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, pthread_cleanup_push(http_process_cleanup, hp); parse_string(spec, http_cmds, hp, vl); retval = hp->fd; - pthread_cleanup_pop(1); + pthread_cleanup_pop(0); + http_process_cleanup(hp); return (retval); } diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c index b8857b3bb..fccc8e35d 100644 --- a/bin/varnishtest/vtc_http2.c +++ b/bin/varnishtest/vtc_http2.c @@ -374,6 +374,7 @@ parse_data(struct stream *s, struct frame *f) struct http *hp; uint32_t size = f->size; char *data = f->data; + CHECK_OBJ_NOTNULL(f, FRAME_MAGIC); CHECK_OBJ_NOTNULL(s, STREAM_MAGIC); CAST_OBJ_NOTNULL(hp, s->hp, HTTP_MAGIC);; @@ -1366,7 +1367,7 @@ cmd_tx11obj(CMD_ARGS) int scheme_done = 1; uint32_t stid = 0, pstid; uint32_t weight = 16; - int exclusive = 0; + uint32_t exclusive = 0; char *buf; struct hpk_iter *iter; struct frame f; @@ -2257,7 +2258,7 @@ cmd_rxmsg(CMD_ARGS) CHKFRAME(f->type, TYPE_CONTINUATION, rcv, *av); } - while (!end_stream && (f = rxstuff(s))) { + while (!end_stream && (f = rxstuff(s)) != NULL) { rcv++; CHKFRAME(f->type, TYPE_DATA, rcv, *av); end_stream = f->flags & END_STREAM; @@ -2695,25 +2696,27 @@ void b64_settings(const struct http *hp, const char *s) { uint16_t i; - uint64_t v; + uint64_t v, vv; const char *buf; int shift; + while (*s) { v = 0; for (shift = 42; shift >= 0; shift -= 6) { if (*s >= 'A' && *s <= 'Z') - v |= (uint64_t)(*s - 'A') << shift; + vv = (*s - 'A'); else if (*s >= 'a' && *s <= 'z') - v |= (uint64_t)((*s - 'a') + 26) << shift; + vv = (*s - 'a') + 26; else if (*s >= '0' && *s <= '9') - v |= (uint64_t)((*s - '0') + 52) << shift; + vv = (*s - '0') + 52; else if (*s == '-') - v |= (uint64_t)62 << shift; + vv = 62; else if (*s == '_') - v |= (uint64_t)63 << shift; + vv = 63; else vtc_fatal(hp->vl, "Bad \"HTTP2-Settings\" header"); + v |= vv << shift; s++; } i = v >> 32; diff --git a/bin/varnishtest/vtc_logexp.c b/bin/varnishtest/vtc_logexp.c index add0f1f46..4735472e2 100644 --- a/bin/varnishtest/vtc_logexp.c +++ b/bin/varnishtest/vtc_logexp.c @@ -153,7 +153,7 @@ struct logexp { int tag_last; int d_arg; - int g_arg; + enum VSL_grouping_e g_arg; char *query; struct vsm *vsm; @@ -171,7 +171,8 @@ logexp_delete_tests(struct logexp *le) struct logexp_test *test; CHECK_OBJ_NOTNULL(le, LOGEXP_MAGIC); - while ((test = VTAILQ_FIRST(&le->tests))) { + while (!VTAILQ_EMPTY(&le->tests)) { + test = VTAILQ_FIRST(&le->tests); CHECK_OBJ_NOTNULL(test, LOGEXP_TEST_MAGIC); VTAILQ_REMOVE(&le->tests, test, list); VSB_destroy(&test->str); @@ -262,7 +263,7 @@ logexp_dispatch(struct VSL_data *vsl, struct VSL_transaction * const pt[], CAST_OBJ_NOTNULL(le, priv, LOGEXP_MAGIC); - for (i = 0; (t = pt[i]); i++) { + for (i = 0; (t = pt[i]) != NULL; i++) { while (1 == VSL_Next(t->c)) { if (!VSL_Match(vsl, t->c)) continue; @@ -510,6 +511,7 @@ void cmd_logexpect(CMD_ARGS) { struct logexp *le, *le2; + int i; (void)priv; (void)cmd; @@ -579,10 +581,11 @@ cmd_logexpect(CMD_ARGS) if (!strcmp(*av, "-g")) { if (av[1] == NULL) vtc_fatal(le->vl, "Missing -g argument"); - le->g_arg = VSLQ_Name2Grouping(av[1], strlen(av[1])); - if (le->g_arg < 0) + i = VSLQ_Name2Grouping(av[1], strlen(av[1])); + if (i < 0) vtc_fatal(le->vl, "Unknown grouping '%s'", av[1]); + le->g_arg = (enum VSL_grouping_e)i; av++; continue; } diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 33ead868e..4876352f2 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -256,7 +256,8 @@ server_thread(void *priv) VTCP_close(&fd); } vtc_log(vl, 2, "Ending"); - pthread_cleanup_pop(1); + pthread_cleanup_pop(0); + vtc_logclose(vl); return (NULL); } @@ -302,7 +303,8 @@ server_dispatch_wrk(void *priv) vtc_fatal(vl, "Shutdown failed: %s", strerror(errno)); VTCP_close(&s->fd); vtc_log(vl, 2, "Ending"); - pthread_cleanup_pop(1); + pthread_cleanup_pop(0); + vtc_logclose(vl); return (NULL); } @@ -321,9 +323,7 @@ server_dispatch_thread(void *priv) assert(s->sock >= 0); vl = vtc_logopen(s->name); -#if !defined(__SUNPRO_C) pthread_cleanup_push(vtc_logclose, vl); -#endif vtc_log(vl, 2, "Dispatch started on %s", s->listen); @@ -342,9 +342,8 @@ server_dispatch_thread(void *priv) s2->run = 1; AZ(pthread_create(&s2->tp, NULL, server_dispatch_wrk, s2)); } -#if !defined(__SUNPRO_C) - pthread_cleanup_pop(1); -#endif + pthread_cleanup_pop(0); + vtc_logclose(vl); NEEDLESS(return(NULL)); } diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c index b7304b50d..ac7e17adb 100644 --- a/bin/varnishtest/vtc_varnish.c +++ b/bin/varnishtest/vtc_varnish.c @@ -223,7 +223,7 @@ varnishlog_thread(void *priv) c = NULL; opt = 0; - while (v->fds[1] > 0 || c != NULL) { + while (v->fds[1] > 0 || c != NULL) { //lint !e845 bug in flint if (c == NULL) { if (vtc_error) break; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:02 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:02 +0000 (UTC) Subject: [6.0] 9bfdda5e3 Fix assertion in HTTP_create() Message-ID: <20180816085302.1BF4B9B9EC@lists.varnish-cache.org> commit 9bfdda5e3fa35df69380e16cf764058bb6919a26 Author: Nils Goroll Date: Mon May 28 10:37:05 2018 +0200 Fix assertion in HTTP_create() For the case that http_max_hdr is not a multiple of the pointer size. Ref #2690 diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c index 6c3e2ce1f..8e41d37b1 100644 --- a/bin/varnishd/cache/cache_http.c +++ b/bin/varnishd/cache/cache_http.c @@ -155,7 +155,7 @@ HTTP_create(void *p, uint16_t nhttp, unsigned len) hp->hd = (void*)(hp + 1); hp->shd = nhttp; hp->hdf = (void*)(hp->hd + nhttp); - assert((unsigned char*)p + len == hp->hdf + nhttp); + assert((unsigned char*)p + len == hp->hdf + PRNDUP(nhttp)); return (hp); } diff --git a/bin/varnishtest/tests/r02690.vtc b/bin/varnishtest/tests/r02690.vtc new file mode 100644 index 000000000..fd133059c --- /dev/null +++ b/bin/varnishtest/tests/r02690.vtc @@ -0,0 +1,129 @@ +varnishtest "Check http_max_hdr values" + +server s1 -repeat 17 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + return(pass); + } +} -start + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 33} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 34} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 35} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 36} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 37} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 38} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 39} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 40} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 41} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 42} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 43} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 44} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 45} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 46} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 47} + +client c1 { + txreq + rxresp +} -run + +varnish v1 -cliok {param.set http_max_hdr 48} + +client c1 { + txreq + rxresp +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:02 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:02 +0000 (UTC) Subject: [6.0] 333dcd8e2 Terminate varnishtop -d automatically Message-ID: <20180816085302.4882A9BA0A@lists.varnish-cache.org> commit 333dcd8e297e1719f2e80f5367d2bb455e814700 Author: Dridi Boukelmoune Date: Tue May 22 09:57:54 2018 +0200 Terminate varnishtop -d automatically Following the documentation, the -d option implies that once processing is done the process should exit. We give it the time to do one last refresh of the screen in curses mode. Refs #2686 diff --git a/bin/varnishtest/tests/u00004.vtc b/bin/varnishtest/tests/u00004.vtc index 4bdc41f1a..28d58ebdc 100644 --- a/bin/varnishtest/tests/u00004.vtc +++ b/bin/varnishtest/tests/u00004.vtc @@ -12,7 +12,8 @@ client c1 { rxresp } -run -shell -expect "fetch" "varnishtop -n ${v1_name} -1 -d" +shell -expect "fetch" "varnishtop -n ${v1_name} -1" +shell -expect "fetch" "varnishtop -n ${v1_name} -d" shell -match "Usage: .*varnishtop " \ "varnishtop -h" diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 5f030c9a1..3035487bd 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -77,13 +77,13 @@ struct top { }; static float period = 60; /* seconds */ -static int end_of_file = 0; static unsigned ntop; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static int f_flag = 0; static unsigned maxfieldlen = 0; static char *ident; +static volatile sig_atomic_t end_of_file = 0; static volatile sig_atomic_t quit = 0; static VRB_HEAD(t_order, top) h_order = VRB_INITIALIZER(&h_order); @@ -204,7 +204,7 @@ static void update(int p) { struct top *tp, *tp2; - int l, len; + int l, len, eof; double t = 0; static time_t last = 0; static unsigned n; @@ -222,7 +222,8 @@ update(int p) AC(erase()); q = ident; len = COLS - strlen(q); - if (end_of_file) + eof = end_of_file; + if (eof) AC(mvprintw(0, len - (1 + 6), "%s (EOF)", q)); else AC(mvprintw(0, len - 1, "%s", q)); @@ -240,7 +241,7 @@ update(int p) len, len, tp->rec_data)); t = tp->count; } - if (end_of_file) + if (eof) continue; tp->count += (1.0/3.0 - tp->count) / (double)n; if (tp->count * 10 < t || l > LINES * 10) { @@ -252,6 +253,8 @@ update(int p) } } AC(refresh()); + if (eof) + quit = 1; } static void * From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:02 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:02 +0000 (UTC) Subject: [6.0] 1116c3aff Remove arbitrary 1.0 threshold in varnishtop -1 Message-ID: <20180816085302.7337A9BA1E@lists.varnish-cache.org> commit 1116c3afff93521df557a80f350fb407aca8bb63 Author: Dridi Boukelmoune Date: Tue May 22 13:39:38 2018 +0200 Remove arbitrary 1.0 threshold in varnishtop -1 With that both -d and -1 options report the same output, with the former limited to the terminal height. While this increases the risk of "never ending" dumps of log records showing only once, the assumption is that varnishtop is useful when someone is looking for something in particular. Restricting the output to the records someone is interested in mitigates the risk. Fixes #2686 diff --git a/bin/varnishtest/tests/r02686.vtc b/bin/varnishtest/tests/r02686.vtc new file mode 100644 index 000000000..53d1aa159 --- /dev/null +++ b/bin/varnishtest/tests/r02686.vtc @@ -0,0 +1,27 @@ +varnishtest "varnishtop -1/-d" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { } -start + +client c1 { + txreq + rxresp +} -run + +process p1 -dump {varnishtop -n ${v1_name} -d -i ReqMethod} -start +process p1 -winsz 30 80 +delay 2 +process p1 -expect-text 1 1 "list length 1" +process p1 -expect-text 1 75 "(EOF)" +process p1 -expect-text 3 6 "1.00 ReqMethod GET" +process p1 -screen_dump -wait + +process p2 -dump {varnishtop -n ${v1_name} -1 -i ReqMethod} -start +process p2 -winsz 30 80 +delay 2 +process p2 -expect-text 1 6 "1.00 ReqMethod GET" +process p2 -screen_dump -wait diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 3035487bd..8bdb0651b 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -322,8 +322,6 @@ dump(void) struct top *tp, *tp2; for (tp = VRB_MIN(t_order, &h_order); tp != NULL; tp = tp2) { tp2 = VRB_NEXT(t_order, &h_order, tp); - if (tp->count <= 1.0) - break; printf("%9.2f %s %*.*s\n", tp->count, VSL_tags[tp->tag], tp->clen, tp->clen, tp->rec_data); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:02 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:02 +0000 (UTC) Subject: [6.0] f9f95617c Some varnishtop -f coverage Message-ID: <20180816085302.A22F49BA3C@lists.varnish-cache.org> commit f9f95617c01b158da649945c6d484fee2437482c Author: Dridi Boukelmoune Date: Tue May 22 14:02:10 2018 +0200 Some varnishtop -f coverage diff --git a/bin/varnishtest/tests/u00004.vtc b/bin/varnishtest/tests/u00004.vtc index 28d58ebdc..71ca1f601 100644 --- a/bin/varnishtest/tests/u00004.vtc +++ b/bin/varnishtest/tests/u00004.vtc @@ -15,6 +15,16 @@ client c1 { shell -expect "fetch" "varnishtop -n ${v1_name} -1" shell -expect "fetch" "varnishtop -n ${v1_name} -d" +# without -f +shell -match "1\\.00 RespHeader Date: [^\\n]+\\n" { + varnishtop -n ${v1_name} -1 -i RespHeader +} + +# with -f +shell -match "1\\.00 RespHeader Date\\n" { + varnishtop -n ${v1_name} -1 -f -i RespHeader +} + shell -match "Usage: .*varnishtop " \ "varnishtop -h" shell -expect "Copyright (c) 2006 Verdens Gang AS" \ diff --git a/bin/varnishtop/varnishtop_options.h b/bin/varnishtop/varnishtop_options.h index dcad73702..ebf8912c1 100644 --- a/bin/varnishtop/varnishtop_options.h +++ b/bin/varnishtop/varnishtop_options.h @@ -40,7 +40,9 @@ #define TOP_OPT_f \ VOPT("f", "[-f]", "First field only", \ "Sort and group only on the first field of each log entry." \ - " This is useful when displaying e.g. stataddr entries," \ + " For log entries in the form ``prefix: value`` it is the" \ + " prefix without the colon that is sorted and grouped." \ + " This is useful when displaying e.g. ReqStart entries," \ " where the first field is the client IP address." \ ) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:02 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:02 +0000 (UTC) Subject: [6.0] d6dbb6429 Fix some punctation and formatting. Message-ID: <20180816085302.D4D739BA4E@lists.varnish-cache.org> commit d6dbb6429d1f256a1b086c818909698cb8730231 Author: Lasse Karstensen Date: Mon May 28 13:10:42 2018 +0200 Fix some punctation and formatting. diff --git a/doc/changes.rst b/doc/changes.rst index dbc2e8600..fd1b498ed 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -82,7 +82,7 @@ VCL and bundled VMODs --------------------- * ``return (fetch)`` is no longer allowed in ``vcl_hit {}``, use - ``return (miss)`` instread. Note that ``return (fetch)`` has been + ``return (miss)`` instead. Note that ``return (fetch)`` has been deprecated since 4.0. * Fix behaviour of restarts to how it was originally intended: @@ -113,11 +113,11 @@ VCL and bundled VMODs * ``beresp.backend.ip`` is retired as of VCL 4.1. -* workspace overflows in ``std.log()`` now trigger a VCL failure +* workspace overflows in ``std.log()`` now trigger a VCL failure. -* workspace overflows in ``std.syslog()`` are ignored +* workspace overflows in ``std.syslog()`` are ignored. -* added ``return(restart)`` from ``vcl_recv{}`` +* added ``return(restart)`` from ``vcl_recv{}``. * The ``alg`` argument of the ``shard`` director ``.reconfigure()`` method has been removed - the consistent hashing ring is now always @@ -190,7 +190,7 @@ VCL and bundled VMODs now need to be named. * Integers in VCL are now 64 bits wide across all platforms - (implemented as ``int64_t`` C type) , but due to implementation + (implemented as ``int64_t`` C type), but due to implementation specifics of the VCL compiler (VCC), integer literals' precision is limited to that of a VCL real (``double`` C type, roughly 53 bits). @@ -206,11 +206,11 @@ Logging / statistics -------------------- * Turned off PROXY protocol debugging by default, can be enabled with - the ``protocol`` debug flag + the ``protocol`` debug flag. -* added ``cache_hit_grace`` statistics counter +* added ``cache_hit_grace`` statistics counter. -* added ``n_lru_limited`` counter +* added ``n_lru_limited`` counter. * The byte counters in ReqAcct now show the numbers reported from the operating system rather than what we anticipated to send. This will give @@ -266,7 +266,7 @@ C APIs (for vmod and utility authors) ``manual``, the auto-SYNOPSIS is left out, for VMOD authors who prefer to write their own. -* All varnish internal ``SHA256*`` symbols have been renamed to +* All Varnish internal ``SHA256*`` symbols have been renamed to ``VSHA256*`` * libvarnish now has ``VNUM_duration()`` to convert from a VCL @@ -281,7 +281,7 @@ C APIs (for vmod and utility authors) * ``__unused`` -> ``v_unused_`` * ``__attribute__((__noreturn__)`` -> ``v_noreturn_`` - * ENUMs are now fixed pointers per vcl +* ENUMs are now fixed pointers per vcl. * Added ``VRT_blob()`` utility function to create a blob as a copy of some chunk of data on the workspace. @@ -294,13 +294,13 @@ Other changes relevant for VMODs -------------------------------- * ``PRIV_*`` function/method arguments are not excluded from - auto-generated vmod documentation + auto-generated vmod documentation. Fixed bugs which may influence VCL behaviour -------------------------------------------- * After reusing a backend connection fails once, a fresh connection - will be opened (2135) + will be opened (2135_). .. _2135: https://github.com/varnishcache/varnish-cache/pull/2135 From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:03 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:03 +0000 (UTC) Subject: [6.0] 9ba61d1b0 sess_fail_* detailled accept error counters Message-ID: <20180816085303.1047B9BA6B@lists.varnish-cache.org> commit 9ba61d1b02a7d3c98be7c4da369a7392c85aea77 Author: Nils Goroll Date: Mon May 28 16:07:27 2018 +0200 sess_fail_* detailled accept error counters We already emitted Debug log records for accept failures, but for all practical purposes this is useless for forensics. These counters will point directly to the root cause for the most common issues with sess_fail (accept failures). sess_fail is preserved as an overall counter as it will most likely be already monitored for many installations. Ref #2622 Conflicts: doc/changes.rst diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc index a2e2d0143..dbcbcdf65 100644 --- a/bin/varnishd/VSC_main.vsc +++ b/bin/varnishd/VSC_main.vsc @@ -33,9 +33,46 @@ .. varnish_vsc:: sess_fail :oneliner: Session accept failures - Count of failures to accept TCP connection. Either the client - changed its mind, or the kernel ran out of some resource like file - descriptors. + Count of failures to accept TCP connection. + + This counter is the sum of the sess_fail_* counters, which + give more detailled information. + +.. varnish_vsc:: sess_fail_econnaborted + :oneliner: Session accept failures: connection aborted + + Detailled reason for sess_fail: Connection aborted by the + client, usually harmless. + +.. varnish_vsc:: sess_fail_eintr + :oneliner: Session accept failures: interrupted system call + + Detailled reason for sess_fail: The accept() call was + interrupted, usually harmless + +.. varnish_vsc:: sess_fail_emfile + :oneliner: Session accept failures: too many open files + + Detailled reason for sess_fail: No file descriptor was + available. Consider raising RLIMIT_NOFILE (see ulimit -n). + +.. varnish_vsc:: sess_fail_ebadf + :oneliner: Session accept failures: bad file descriptor + + Detailled reason for sess_fail: The listen socket file + descriptor was invalid. Should never happen. + +.. varnish_vsc:: sess_fail_enomem + :oneliner: Session accept failures: not enough memory + + Detailled reason for sess_fail: Most likely insufficient + socket buffer memory. Should never happen + +.. varnish_vsc:: sess_fail_other + :oneliner: Session accept failures: other + + Detailled reason for sess_fail: neither of the above, see + Debug log (varnishlog -g raw -I Debug:^Accept). .. varnish_vsc:: client_req_400 :oneliner: Client requests received, subject to 400 errors diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 6973d01d8..455697fe1 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -489,23 +489,32 @@ vca_accept_task(struct worker *wrk, void *arg) if (i < 0) { switch (errno) { case ECONNABORTED: + wrk->stats->sess_fail_econnaborted++; + break; + case EINTR: + wrk->stats->sess_fail_eintr++; break; case EMFILE: - VSL(SLT_Debug, ls->sock, "Too many open files"); + wrk->stats->sess_fail_emfile++; vca_pace_bad(); break; case EBADF: - VSL(SLT_Debug, ls->sock, "Accept failed: %s", - strerror(errno)); + wrk->stats->sess_fail_ebadf++; + vca_pace_bad(); + break; + case ENOBUFS: + case ENOMEM: + wrk->stats->sess_fail_enomem++; vca_pace_bad(); break; default: - VSL(SLT_Debug, ls->sock, "Accept failed: %s", - strerror(errno)); + wrk->stats->sess_fail_other++; vca_pace_bad(); break; } wrk->stats->sess_fail++; + VSL(SLT_Debug, ls->sock, "Accept failed: %s", + strerror(errno)); (void)Pool_TrySumstat(wrk); continue; } diff --git a/doc/changes.rst b/doc/changes.rst index fd1b498ed..81b7d0a6f 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -31,6 +31,21 @@ release process. Varnish Cache 6.0.1 (ongoing) ================================ +varnishstat +----------- + +* The counters + + * ``sess_fail_econnaborted`` + * ``sess_fail_eintr`` + * ``sess_fail_emfile`` + * ``sess_fail_ebadf`` + * ``sess_fail_enomem`` + * ``sess_fail_other`` + + now break down the detailled reason for session accept failures, the + sum of which continues to be counted in ``sess_fail``. + VCL and bundled VMODs --------------------- From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:03 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:03 +0000 (UTC) Subject: [6.0] 3cbba137f Use 'process' when terminal/curses is involved Message-ID: <20180816085303.3D0289BA80@lists.varnish-cache.org> commit 3cbba137fdbe6f612742b3868c4fcfea39e600c1 Author: Poul-Henning Kamp Date: Mon May 28 16:20:01 2018 +0000 Use 'process' when terminal/curses is involved diff --git a/bin/varnishtest/tests/u00004.vtc b/bin/varnishtest/tests/u00004.vtc index 71ca1f601..5435f9865 100644 --- a/bin/varnishtest/tests/u00004.vtc +++ b/bin/varnishtest/tests/u00004.vtc @@ -13,7 +13,9 @@ client c1 { } -run shell -expect "fetch" "varnishtop -n ${v1_name} -1" -shell -expect "fetch" "varnishtop -n ${v1_name} -d" + +process p1 "varnishtop -n ${v1_name} -d" -run -screen_dump +process p1 -expect-text 0 0 fetch # without -f shell -match "1\\.00 RespHeader Date: [^\\n]+\\n" { From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:03 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:03 +0000 (UTC) Subject: [6.0] 3c1728a8c Spelling Message-ID: <20180816085303.65CFF9BAA8@lists.varnish-cache.org> commit 3c1728a8cda76fcbaf6017fc133647735b2e8690 Author: Federico G. Schwindt Date: Mon May 28 21:04:17 2018 +0100 Spelling diff --git a/bin/varnishd/VSC_main.vsc b/bin/varnishd/VSC_main.vsc index dbcbcdf65..4749eb5c2 100644 --- a/bin/varnishd/VSC_main.vsc +++ b/bin/varnishd/VSC_main.vsc @@ -36,42 +36,42 @@ Count of failures to accept TCP connection. This counter is the sum of the sess_fail_* counters, which - give more detailled information. + give more detailed information. .. varnish_vsc:: sess_fail_econnaborted :oneliner: Session accept failures: connection aborted - Detailled reason for sess_fail: Connection aborted by the + Detailed reason for sess_fail: Connection aborted by the client, usually harmless. .. varnish_vsc:: sess_fail_eintr :oneliner: Session accept failures: interrupted system call - Detailled reason for sess_fail: The accept() call was + Detailed reason for sess_fail: The accept() call was interrupted, usually harmless .. varnish_vsc:: sess_fail_emfile :oneliner: Session accept failures: too many open files - Detailled reason for sess_fail: No file descriptor was + Detailed reason for sess_fail: No file descriptor was available. Consider raising RLIMIT_NOFILE (see ulimit -n). .. varnish_vsc:: sess_fail_ebadf :oneliner: Session accept failures: bad file descriptor - Detailled reason for sess_fail: The listen socket file + Detailed reason for sess_fail: The listen socket file descriptor was invalid. Should never happen. .. varnish_vsc:: sess_fail_enomem :oneliner: Session accept failures: not enough memory - Detailled reason for sess_fail: Most likely insufficient + Detailed reason for sess_fail: Most likely insufficient socket buffer memory. Should never happen .. varnish_vsc:: sess_fail_other :oneliner: Session accept failures: other - Detailled reason for sess_fail: neither of the above, see + Detailed reason for sess_fail: neither of the above, see Debug log (varnishlog -g raw -I Debug:^Accept). .. varnish_vsc:: client_req_400 @@ -374,7 +374,7 @@ .. varnish_vsc:: s_synth - :oneliner: Total synthethic responses made + :oneliner: Total synthetic responses made .. varnish_vsc:: s_req_hdrbytes From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:03 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:03 +0000 (UTC) Subject: [6.0] 365341d67 Whitespace OCD Message-ID: <20180816085303.931669BAFC@lists.varnish-cache.org> commit 365341d6794ec3bdb281b86eddd5fb90453369b4 Author: Poul-Henning Kamp Date: Tue May 29 09:56:58 2018 +0000 Whitespace OCD diff --git a/bin/varnishtest/tests/r02686.vtc b/bin/varnishtest/tests/r02686.vtc index 53d1aa159..eb85b9914 100644 --- a/bin/varnishtest/tests/r02686.vtc +++ b/bin/varnishtest/tests/r02686.vtc @@ -1,15 +1,15 @@ varnishtest "varnishtop -1/-d" server s1 { - rxreq - txresp + rxreq + txresp } -start varnish v1 -vcl+backend { } -start client c1 { - txreq - rxresp + txreq + rxresp } -run process p1 -dump {varnishtop -n ${v1_name} -d -i ReqMethod} -start From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:03 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:03 +0000 (UTC) Subject: [6.0] fca0f4df4 Add a version of VSS_resolver() where you specify the socktype. Message-ID: <20180816085303.BECED9BB1E@lists.varnish-cache.org> commit fca0f4df4f55ba5c3329f4c62b9127c24a13b865 Author: Poul-Henning Kamp Date: Tue May 29 11:54:21 2018 +0000 Add a version of VSS_resolver() where you specify the socktype. diff --git a/include/vss.h b/include/vss.h index 14b935636..aa645bdc7 100644 --- a/include/vss.h +++ b/include/vss.h @@ -32,3 +32,5 @@ struct suckaddr; typedef int vss_resolved_f(void *priv, const struct suckaddr *); int VSS_resolver(const char *addr, const char *def_port, vss_resolved_f *func, void *priv, const char **err); +int VSS_resolver_socktype(const char *addr, const char *def_port, + vss_resolved_f *func, void *priv, const char **err, int socktype); diff --git a/lib/libvarnish/vss.c b/lib/libvarnish/vss.c index 29c66be64..7282019de 100644 --- a/lib/libvarnish/vss.c +++ b/lib/libvarnish/vss.c @@ -105,8 +105,8 @@ vss_parse(char *str, char **addr, char **port) */ int -VSS_resolver(const char *addr, const char *def_port, vss_resolved_f *func, - void *priv, const char **err) +VSS_resolver_socktype(const char *addr, const char *def_port, + vss_resolved_f *func, void *priv, const char **err, int socktype) { struct addrinfo hints, *res0, *res; struct suckaddr *vsa; @@ -126,7 +126,7 @@ VSS_resolver(const char *addr, const char *def_port, vss_resolved_f *func, def_port = adp; memset(&hints, 0, sizeof hints); - hints.ai_socktype = SOCK_STREAM; + hints.ai_socktype = socktype; hints.ai_flags = AI_PASSIVE; ret = getaddrinfo(hop, def_port, &hints, &res0); free(h); @@ -146,3 +146,11 @@ VSS_resolver(const char *addr, const char *def_port, vss_resolved_f *func, freeaddrinfo(res0); return (ret); } + +int +VSS_resolver(const char *addr, const char *def_port, vss_resolved_f *func, + void *priv, const char **err) +{ + return (VSS_resolver_socktype( + addr, def_port, func, priv, err, SOCK_STREAM)); +} From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:03 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:03 +0000 (UTC) Subject: [6.0] ed4e07b08 Add a syslog-server facility for the benefit of HAproxy testers. Message-ID: <20180816085303.F36719BB49@lists.varnish-cache.org> commit ed4e07b08366eb59255440576d3654013e585de2 Author: Poul-Henning Kamp Date: Tue May 29 12:11:19 2018 +0000 Add a syslog-server facility for the benefit of HAproxy testers. Submitted by: Fr?d?ric L?caille Hacked to pieces by: phk diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 392b02a13..0deef9cfb 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -57,6 +57,7 @@ varnishtest_SOURCES = \ vtc_proxy.c \ vtc_server.c \ vtc_subr.c \ + vtc_syslog.c \ vtc_varnish.c varnishtest_LDADD = \ diff --git a/bin/varnishtest/Makefile.phk b/bin/varnishtest/Makefile.phk index b50535d50..b406ccec4 100644 --- a/bin/varnishtest/Makefile.phk +++ b/bin/varnishtest/Makefile.phk @@ -6,6 +6,7 @@ PROG_SRC += vtc_logexp.c PROG_SRC += vtc_main.c PROG_SRC += vtc_barrier.c PROG_SRC += vtc_server.c +PROG_SRC += vtc_syslog.c PROG_SRC += vtc_varnish.c PROG_SRC += vtc_process.c diff --git a/bin/varnishtest/cmds.h b/bin/varnishtest/cmds.h index 290237d7e..e856e6084 100644 --- a/bin/varnishtest/cmds.h +++ b/bin/varnishtest/cmds.h @@ -40,6 +40,7 @@ CMD(process) CMD(server) CMD(setenv) CMD(shell) +CMD(syslog) CMD(varnish) CMD(varnishtest) #undef CMD diff --git a/bin/varnishtest/tests/h00005.vtc b/bin/varnishtest/tests/h00005.vtc new file mode 100644 index 000000000..44cf902e7 --- /dev/null +++ b/bin/varnishtest/tests/h00005.vtc @@ -0,0 +1,45 @@ +varnishtest "Exercise varnishtest syslog facility" + +feature ignore_unknown_macro +feature cmd {haproxy --version 2>&1 | grep -q 'HA-Proxy version'} + +server s1 { + rxreq + txresp +} -start + +syslog sl1 -level notice -bind "127.0.0.1:0" { + recv + recv + recv info + expect ~ \"dip\":\"${h1_fe_1_addr} +} -start + +haproxy h1 -conf { + global + log ${sl1_addr}:${sl1_port} local0 + + defaults + log global + timeout connect 3000 + timeout client 5 + timeout server 10000 + + frontend fe1 + bind "fd@${fe_1}" + mode tcp + log-format {\"dip\":\"%fi\",\"dport\":\"%fp\"} + default_backend be1 + + backend be1 + server srv1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_1_sock} { + txreq -url "/" + delay 0.02 + rxresp +} -run + +syslog sl1 -wait + diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index c6c58979e..69b2d3db0 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -472,6 +472,7 @@ exec_file(const char *fn, const char *script, const char *tmpdir, init_macro(); init_server(); + init_syslog(); vsb = VSB_new_auto(); AN(vsb); diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h index 8ad4a5a16..6ebff08a5 100644 --- a/bin/varnishtest/vtc.h +++ b/bin/varnishtest/vtc.h @@ -85,6 +85,7 @@ extern int feature_dns; extern int ign_unknown_macro; void init_server(void); +void init_syslog(void); int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd, const char *addr); diff --git a/bin/varnishtest/vtc_syslog.c b/bin/varnishtest/vtc_syslog.c new file mode 100644 index 000000000..2ef8a8559 --- /dev/null +++ b/bin/varnishtest/vtc_syslog.c @@ -0,0 +1,649 @@ +/*- + * Copyright (c) 2008-2010 Varnish Software AS + * All rights reserved. + * + * Author: Fr?d?ric L?caille + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "vsa.h" +#include "vss.h" +#include "vtcp.h" +#include "vre.h" + +#include "vtc.h" + +struct syslog_srv { + unsigned magic; +#define SYSLOG_SRV_MAGIC 0xbf28a692 + char *name; + struct vtclog *vl; + VTAILQ_ENTRY(syslog_srv) list; + char run; + + unsigned repeat; + char *spec; + + int sock; + char bind[256]; + int lvl; + + pthread_t tp; + ssize_t rxbuf_left; + size_t rxbuf_sz; + char *rxbuf; + double timeout; +}; + +static pthread_mutex_t syslog_mtx; + +static VTAILQ_HEAD(, syslog_srv) syslogs = + VTAILQ_HEAD_INITIALIZER(syslogs); + +static const char * const syslog_levels[] = { + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + NULL, +}; + +static int +get_syslog_level(struct vtclog *vl, const char *lvl) +{ + int i; + + for (i = 0; syslog_levels[i]; i++) + if (!strcmp(lvl, syslog_levels[i])) + return (i); + vtc_fatal(vl, "wrong syslog level '%s'\n", lvl); +} + +/*-------------------------------------------------------------------- + * Check if a UDP syscall return value is fatal + * XXX: Largely copied from VTCP, not sure if really applicable + */ + +static int +VUDP_Check(int a) +{ + if (a == 0) + return (1); + if (errno == ECONNRESET) + return (1); +#if (defined (__SVR4) && defined (__sun)) || defined (__NetBSD__) + /* + * Solaris returns EINVAL if the other end unexpectedly reset the + * connection. + * This is a bug in Solaris and documented behaviour on NetBSD. + */ + if (errno == EINVAL || errno == ETIMEDOUT || errno == EPIPE) + return (1); +#elif defined (__APPLE__) + /* + * MacOS returns EINVAL if the other end unexpectedly reset + * the connection. + */ + if (errno == EINVAL) + return (1); +#endif + return (0); +} + +/*-------------------------------------------------------------------- + * When closing a UDP connection, a couple of errno's are legit, we + * can't be held responsible for the other end wanting to talk to us. + */ + +static void +VUDP_close(int *s) +{ + int i; + + i = close(*s); + + assert(VUDP_Check(i)); + *s = -1; +} + +/*-------------------------------------------------------------------- + * Given a struct suckaddr, open a socket of the appropriate type, and bind + * it to the requested address. + * + * If the address is an IPv6 address, the IPV6_V6ONLY option is set to + * avoid conflicts between INADDR_ANY and IN6ADDR_ANY. + */ + +static int +VUDP_bind(const struct suckaddr *sa, const char **errp) +{ + int sd, val, e; + socklen_t sl; + const struct sockaddr *so; + int proto; + + if (errp != NULL) + *errp = NULL; + + proto = VSA_Get_Proto(sa); + sd = socket(proto, SOCK_DGRAM, 0); + if (sd < 0) { + if (errp != NULL) + *errp = "socket(2)"; + return (-1); + } + val = 1; + if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) != 0) { + if (errp != NULL) + *errp = "setsockopt(SO_REUSEADDR, 1)"; + e = errno; + closefd(&sd); + errno = e; + return (-1); + } + +#ifdef IPV6_V6ONLY + /* forcibly use separate sockets for IPv4 and IPv6 */ + val = 1; + if (proto == AF_INET6 && + setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val) != 0) { + if (errp != NULL) + *errp = "setsockopt(IPV6_V6ONLY, 1)"; + e = errno; + closefd(&sd); + errno = e; + return (-1); + } +#endif + so = VSA_Get_Sockaddr(sa, &sl); + if (bind(sd, so, sl) != 0) { + if (errp != NULL) + *errp = "bind(2)"; + e = errno; + closefd(&sd); + errno = e; + return (-1); + } + return (sd); +} + +/*--------------------------------------------------------------------*/ + +struct udp_helper { + const char **errp; +}; + +static int v_matchproto_(vss_resolved_f) +vudp_lo_cb(void *priv, const struct suckaddr *sa) +{ + int sock; + struct udp_helper *hp = priv; + + sock = VUDP_bind(sa, hp->errp); + if (sock > 0) { + *hp->errp = NULL; + return (sock); + } + AN(*hp->errp); + return (0); +} + +static int +VUDP_bind_on(const char *addr, const char *def_port, const char **errp) +{ + struct udp_helper h; + int sock; + + h.errp = errp; + + sock = VSS_resolver_socktype( + addr, def_port, vudp_lo_cb, &h, errp, SOCK_DGRAM); + if (*errp != NULL) + return (-1); + return (sock); +} + +/********************************************************************** + * Allocate and initialize a syslog + */ + +static struct syslog_srv * +syslog_new(const char *name, struct vtclog *vl) +{ + struct syslog_srv *s; + + VTC_CHECK_NAME(vl, name, "Syslog", 's'); + ALLOC_OBJ(s, SYSLOG_SRV_MAGIC); + AN(s); + REPLACE(s->name, name); + s->vl = vtc_logopen(s->name); + AN(s->vl); + + bprintf(s->bind, "%s", "127.0.0.1 0"); + s->repeat = 1; + s->sock = -1; + s->lvl = -1; + s->timeout = vtc_maxdur * .5; // XXX + + vl = vtc_logopen(s->name); + AN(vl); + + s->rxbuf_sz = s->rxbuf_left = 2048*1024; + s->rxbuf = malloc(s->rxbuf_sz); /* XXX */ + AN(s->rxbuf); + + AZ(pthread_mutex_lock(&syslog_mtx)); + VTAILQ_INSERT_TAIL(&syslogs, s, list); + AZ(pthread_mutex_unlock(&syslog_mtx)); + return (s); +} + +/********************************************************************** + * Clean up a syslog + */ + +static void +syslog_delete(struct syslog_srv *s) +{ + + CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC); + macro_undef(s->vl, s->name, "addr"); + macro_undef(s->vl, s->name, "port"); + macro_undef(s->vl, s->name, "sock"); + vtc_logclose(s->vl); + free(s->name); + free(s->rxbuf); + /* XXX: MEMLEAK (?) (VSS ??) */ + FREE_OBJ(s); +} + +static void +syslog_rx(const struct syslog_srv *s, int lvl) +{ + ssize_t ret; + + while (!vtc_error) { + /* Pointers to syslog priority value (see , rfc5424). */ + char *prib, *prie, *end; + unsigned int prival; + + VTCP_set_read_timeout(s->sock, s->timeout); + + ret = recv(s->sock, s->rxbuf, s->rxbuf_sz - 1, 0); + if (ret < 0) { + if (errno == EINTR) + continue; + + vtc_fatal(s->vl, + "%s: recv failed (fd: %d read: %s", __func__, + s->sock, strerror(errno)); + } + if (ret == 0) + vtc_fatal(s->vl, + "syslog rx timeout (fd: %d %.3fs ret: %zd)", + s->sock, s->timeout, ret); + + s->rxbuf[ret] = '\0'; + vtc_dump(s->vl, 4, "syslog", s->rxbuf, ret); + + prib = s->rxbuf; + if (*prib++ != '<') + vtc_fatal(s->vl, "syslog PRI, no '<'"); + prie = strchr(prib, '>'); + if (prie == NULL) + vtc_fatal(s->vl, "syslog PRI, no '>'"); + + prival = strtoul(prib, &end, 10); + if (end != prie) + vtc_fatal(s->vl, "syslog PRI, bad number"); + + if (lvl >= 0 && lvl == (prival & 0x7)) + return; + } +} + +/********************************************************************** + * Syslog server bind + */ + +static void +syslog_bind(struct syslog_srv *s) +{ + const char *err; + char aaddr[VTCP_ADDRBUFSIZE]; + char aport[VTCP_PORTBUFSIZE]; + + CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC); + + if (s->sock >= 0) + VUDP_close(&s->sock); + s->sock = VUDP_bind_on(s->bind, "0", &err); + if (err != NULL) + vtc_fatal(s->vl, + "Syslog server bind address (%s) cannot be resolved: %s", + s->bind, err); + assert(s->sock > 0); + VTCP_myname(s->sock, aaddr, sizeof aaddr, aport, sizeof aport); + macro_def(s->vl, s->name, "addr", "%s", aaddr); + macro_def(s->vl, s->name, "port", "%s", aport); + macro_def(s->vl, s->name, "sock", "%s %s", aaddr, aport); + /* Record the actual port, and reuse it on subsequent starts */ + bprintf(s->bind, "%s %s", aaddr, aport); +} + +static void v_matchproto_(cmd_f) +cmd_syslog_expect(CMD_ARGS) +{ + struct syslog_srv *s; + vre_t *vre; + const char *error; + int erroroffset, i, ret; + char *cmp, *spec; + + (void)vl; + (void)cmd; + CAST_OBJ_NOTNULL(s, priv, SYSLOG_SRV_MAGIC); + AZ(strcmp(av[0], "expect")); + av++; + + cmp = av[0]; + spec = av[1]; + AN(cmp); + AN(spec); + AZ(av[2]); + + assert(!strcmp(cmp, "~") || !strcmp(cmp, "!~")); + + vre = VRE_compile(spec, 0, &error, &erroroffset); + if (!vre) + vtc_fatal(s->vl, "REGEXP error: '%s' (@%d) (%s)", + error, erroroffset, spec); + + i = VRE_exec(vre, s->rxbuf, strlen(s->rxbuf), 0, 0, NULL, 0, 0); + + VRE_free(&vre); + + ret = (i >= 0 && *cmp == '~') || (i < 0 && *cmp == '!'); + if (!ret) + vtc_fatal(s->vl, "EXPECT FAILED %s \"%s\"", cmp, spec); + else + vtc_log(s->vl, 4, "EXPECT MATCH %s \"%s\"", cmp, spec); +} + +static void v_matchproto_(cmd_f) +cmd_syslog_recv(CMD_ARGS) +{ + int lvl; + struct syslog_srv *s; + + CAST_OBJ_NOTNULL(s, priv, SYSLOG_SRV_MAGIC); + (void)cmd; + (void)vl; + AZ(strcmp(av[0], "recv")); + av++; + if (av[0] == NULL) + lvl = s->lvl; + else + lvl = get_syslog_level(vl, av[0]); + + syslog_rx(s, lvl); +} + +static const struct cmds syslog_cmds[] = { +#define CMD_SYSLOG(n) { #n, cmd_syslog_##n }, + /* session */ + CMD_SYSLOG(expect) + CMD_SYSLOG(recv) +#undef CMD_SYSLOG +}; + +/********************************************************************** + * Syslog server thread + */ + +static void * +syslog_thread(void *priv) +{ + struct syslog_srv *s; + int i; + + CAST_OBJ_NOTNULL(s, priv, SYSLOG_SRV_MAGIC); + assert(s->sock >= 0); + + vtc_log(s->vl, 2, "Started on %s (level: %d)", s->bind, s->lvl); + for (i = 0; i < s->repeat; i++) { + if (s->repeat > 1) + vtc_log(s->vl, 3, "Iteration %d", i); + parse_string(s->spec, syslog_cmds, s, s->vl); + vtc_log(s->vl, 3, "shutting fd %d", s->sock); + } + VUDP_close(&s->sock); + vtc_log(s->vl, 2, "Ending"); + return (NULL); +} + +/********************************************************************** + * Start the syslog thread + */ + +static void +syslog_start(struct syslog_srv *s) +{ + CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC); + vtc_log(s->vl, 2, "Starting syslog server"); + if (s->sock == -1) + syslog_bind(s); + vtc_log(s->vl, 1, "Bound on %s", s->bind); + s->run = 1; + AZ(pthread_create(&s->tp, NULL, syslog_thread, s)); +} + +/********************************************************************** + * Force stop the syslog thread + */ + +static void +syslog_stop(struct syslog_srv *s) +{ + void *res; + + CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC); + vtc_log(s->vl, 2, "Stopping for syslog server"); + (void)pthread_cancel(s->tp); + AZ(pthread_join(s->tp, &res)); + s->tp = 0; + s->run = 0; +} + +/********************************************************************** + * Wait for syslog thread to stop + */ + +static void +syslog_wait(struct syslog_srv *s) +{ + void *res; + + CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC); + vtc_log(s->vl, 2, "Waiting for syslog server (%d)", s->sock); + AZ(pthread_join(s->tp, &res)); + if (res != NULL && !vtc_stop) + vtc_fatal(s->vl, "Syslog server returned \"%p\"", + (char *)res); + s->tp = 0; + s->run = 0; +} + +/* SECTION: syslog syslog + * + * Define and interact with syslog instances. + * + * To define a syslog server, you'll use this syntax:: + * + * syslog sNAME + * + * Arguments: + * + * sNAME + * Identify the syslog server with a string which must start with 's'. + * + * \-level STRING + * Set the default syslog priority level used by any subsequent "recv" + * command. + * Any syslog dgram with a different level will be skipped by + * "recv" command. This default level value may be superseded + * by "recv" command if supplied as first argument: "recv ". + * + * \-start + * Start the syslog server thread in the background. + * + * \-repeat + * Instead of processing the specification only once, do it + * NUMBER times. + * + * \-bind + * Bind the syslog socket to a local address. + * + * \-wait + * Wait for that thread to terminate. + * + * \-stop + * Stop the syslog server thread. + */ + +void v_matchproto_(cmd_f) +cmd_syslog(CMD_ARGS) +{ + struct syslog_srv *s; + + (void)priv; + (void)cmd; + + if (av == NULL) { + /* Reset and free */ + do { + AZ(pthread_mutex_lock(&syslog_mtx)); + s = VTAILQ_FIRST(&syslogs); + CHECK_OBJ_ORNULL(s, SYSLOG_SRV_MAGIC); + if (s != NULL) + VTAILQ_REMOVE(&syslogs, s, list); + AZ(pthread_mutex_unlock(&syslog_mtx)); + if (s != NULL) { + if (s->run) { + (void)pthread_cancel(s->tp); + syslog_wait(s); + } + if (s->sock >= 0) + VUDP_close(&s->sock); + syslog_delete(s); + } + } while (s != NULL); + return; + } + + AZ(strcmp(av[0], "syslog")); + av++; + + AZ(pthread_mutex_lock(&syslog_mtx)); + VTAILQ_FOREACH(s, &syslogs, list) + if (!strcmp(s->name, av[0])) + break; + AZ(pthread_mutex_unlock(&syslog_mtx)); + if (s == NULL) + s = syslog_new(av[0], vl); + CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC); + av++; + + for (; *av != NULL; av++) { + if (vtc_error) + break; + if (!strcmp(*av, "-wait")) { + if (!s->run) + vtc_fatal(s->vl, "Syslog server not -started"); + syslog_wait(s); + continue; + } + + if (!strcmp(*av, "-stop")) { + syslog_stop(s); + continue; + } + + /* + * We do an implict -wait if people muck about with a + * running syslog. + * This only works if the previous ->spec has completed + */ + if (s->run) + syslog_wait(s); + + AZ(s->run); + if (!strcmp(*av, "-repeat")) { + AN(av[1]); + s->repeat = atoi(av[1]); + av++; + continue; + } + if (!strcmp(*av, "-bind")) { + AN(av[1]); + bprintf(s->bind, "%s", av[1]); + av++; + syslog_bind(s); + continue; + } + if (!strcmp(*av, "-level")) { + AN(av[1]); + s->lvl = get_syslog_level(vl, av[1]); + av++; + continue; + } + if (!strcmp(*av, "-start")) { + syslog_start(s); + continue; + } + if (**av == '-') + vtc_fatal(s->vl, "Unknown syslog argument: %s", *av); + s->spec = *av; + } +} + +void +init_syslog(void) +{ + AZ(pthread_mutex_init(&syslog_mtx, NULL)); +} From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:04 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:04 +0000 (UTC) Subject: [6.0] 5b7a0ca50 Force haproxy onto "localhost" addresses, to make it possible to match syslog-output. Message-ID: <20180816085304.22DE49BB63@lists.varnish-cache.org> commit 5b7a0ca506d5a4b0712c4199dda1fc54f6079998 Author: Poul-Henning Kamp Date: Tue May 29 16:00:21 2018 +0000 Force haproxy onto "localhost" addresses, to make it possible to match syslog-output. diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 88162a951..3cc12fe28 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -389,7 +389,7 @@ haproxy_build_backends(const struct haproxy *h, const char *vsb_data) break; *q++ = '\0'; - sock = VTCP_listen_on(":0", NULL, 1, &err); + sock = VTCP_listen_on("localhost:0", NULL, 1, &err); if (err != NULL) vtc_fatal(h->vl, "Create listen socket failed: %s", err); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:04 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:04 +0000 (UTC) Subject: [6.0] 3589177f6 Include haproxy and syslog in VTC documentation Message-ID: <20180816085304.549D99BB6F@lists.varnish-cache.org> commit 3589177f686d30ea9e5e0436fb2d4a8f6320d621 Author: Poul-Henning Kamp Date: Tue May 29 16:01:14 2018 +0000 Include haproxy and syslog in VTC documentation diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am index 04fa9db79..f2d0df765 100644 --- a/doc/sphinx/Makefile.am +++ b/doc/sphinx/Makefile.am @@ -184,10 +184,12 @@ BUILT_SOURCES += include/vsl-tags.rst VTCSYN_SRC = $(top_srcdir)/bin/varnishtest/vtc.c \ $(top_srcdir)/bin/varnishtest/vtc_barrier.c \ + $(top_srcdir)/bin/varnishtest/vtc_haproxy.c \ $(top_srcdir)/bin/varnishtest/vtc_http.c \ $(top_srcdir)/bin/varnishtest/vtc_http2.c \ $(top_srcdir)/bin/varnishtest/vtc_logexp.c \ $(top_srcdir)/bin/varnishtest/vtc_process.c \ + $(top_srcdir)/bin/varnishtest/vtc_syslog.c \ $(top_srcdir)/bin/varnishtest/vtc_varnish.c include/vtc-syntax.rst: vtc-syntax.py $(VTCSYN_SRC) $(PYTHON) $(top_srcdir)/doc/sphinx/vtc-syntax.py $(VTCSYN_SRC) > $@ From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:04 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:04 +0000 (UTC) Subject: [6.0] d6792f992 Match also the ending double-quotes Message-ID: <20180816085304.8CE579BB96@lists.varnish-cache.org> commit d6792f99200107a09af7f84d2e94052bcfb7d749 Author: Poul-Henning Kamp Date: Tue May 29 16:04:05 2018 +0000 Match also the ending double-quotes diff --git a/bin/varnishtest/tests/h00005.vtc b/bin/varnishtest/tests/h00005.vtc index 44cf902e7..66427b5a4 100644 --- a/bin/varnishtest/tests/h00005.vtc +++ b/bin/varnishtest/tests/h00005.vtc @@ -12,7 +12,7 @@ syslog sl1 -level notice -bind "127.0.0.1:0" { recv recv recv info - expect ~ \"dip\":\"${h1_fe_1_addr} + expect ~ \"dip\":\"${h1_fe_1_addr}\" } -start haproxy h1 -conf { From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:04 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:04 +0000 (UTC) Subject: [6.0] ab6cf6cfe Allow multiple imports of the same VMOD, if the file_id is identical. Message-ID: <20180816085304.B7B009BBA2@lists.varnish-cache.org> commit ab6cf6cfeba5dbb36a024d7ff523eb56d14209c0 Author: Poul-Henning Kamp Date: Wed May 30 07:05:24 2018 +0000 Allow multiple imports of the same VMOD, if the file_id is identical. diff --git a/bin/varnishtest/tests/m00001.vtc b/bin/varnishtest/tests/m00001.vtc index 7c79f891c..6e0781262 100644 --- a/bin/varnishtest/tests/m00001.vtc +++ b/bin/varnishtest/tests/m00001.vtc @@ -66,11 +66,6 @@ varnish v1 -cliok "vcl.discard vcl2" varnish v1 -cliok "vcl.list" varnish v1 -cliok "debug.vmod" -varnish v1 -errvcl {Module std already imported.} { - import std; - import std; -} - varnish v1 -errvcl {Symbol type (vmod) can not be used in expression.} { import std; diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c index 1699ff774..f34b0f3b1 100644 --- a/lib/libvcc/vcc_vmod.c +++ b/lib/libvcc/vcc_vmod.c @@ -163,6 +163,7 @@ vcc_ParseImport(struct vcc *tl) struct symbol *msym; const struct vmod_data *vmd; struct vjsn *vj; + int again = 0; t1 = tl->t; SkipToken(tl, ID); /* "import" */ @@ -182,19 +183,15 @@ vcc_ParseImport(struct vcc *tl) return; } if (msym != NULL) { - VSB_printf(tl->sb, "Module %.*s already imported.\n", - PF(mod)); - vcc_ErrWhere2(tl, t1, tl->t); - VSB_printf(tl->sb, "Previous import was here:\n"); - vcc_ErrWhere2(tl, msym->def_b, msym->def_e); - return; - } + again = 1; + } else { - msym = VCC_SymbolGet(tl, SYM_VMOD, SYMTAB_CREATE, XREF_NONE); - ERRCHK(tl); - AN(msym); - msym->def_b = t1; - msym->def_e = tl->t; + msym = VCC_SymbolGet(tl, SYM_VMOD, SYMTAB_CREATE, XREF_NONE); + ERRCHK(tl); + AN(msym); + msym->def_b = t1; + msym->def_e = tl->t; + } if (tl->t->tok == ID) { if (!vcc_IdIs(tl->t, "from")) { @@ -223,6 +220,10 @@ vcc_ParseImport(struct vcc *tl) SkipToken(tl, ';'); + if (!again) + msym->def_e = tl->t; + + if (VFIL_searchpath(tl->vmod_path, vcc_path_dlopen, &hdl, fn, &fnpx)) { VSB_printf(tl->sb, "Could not load VMOD %.*s\n", PF(mod)); @@ -287,6 +288,19 @@ vcc_ParseImport(struct vcc *tl) return; } + if (again && strcmp(vmd->file_id, msym->extra)) { + VSB_printf(tl->sb, + "Different version of module %.*s already imported.\n", + PF(mod)); + vcc_ErrWhere2(tl, t1, tl->t); + VSB_printf(tl->sb, "Previous import was here:\n"); + vcc_ErrWhere2(tl, msym->def_b, msym->def_e); + } + if (again) { + AZ(dlclose(hdl)); + return; + } + ifp = New_IniFin(tl); VSB_printf(ifp->ini, "\tif (VRT_Vmod_Init(ctx,\n"); @@ -317,6 +331,7 @@ vcc_ParseImport(struct vcc *tl) AN(vj); msym->eval_priv = vj; msym->wildcard = vcc_json_wildcard; + msym->extra = TlDup(tl, vmd->file_id); vcc_json_always(tl, msym); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:04 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:04 +0000 (UTC) Subject: [6.0] f12d4c026 h2: Move the frame completion check up Message-ID: <20180816085304.F17CD9BBB8@lists.varnish-cache.org> commit f12d4c0266a6b499d2936c03fcaeb030aa1158a4 Author: Dag Haavi Finstad Date: Mon May 28 11:14:59 2018 +0200 h2: Move the frame completion check up Avoid failing sessions with pipelined data. diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 1da101a0e..1bba9b332 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -830,11 +830,12 @@ h2_frame_complete(struct http_conn *htc) if (l < 9) return (HTC_S_MORE); u = vbe32dec(htc->rxbuf_b) >> 8; - if (l > h2->local_settings.max_frame_size + 9) + if (l >= u + 9) + return (HTC_S_COMPLETE); + else if (l > h2->local_settings.max_frame_size + 9) return (HTC_S_OVERFLOW); - if (l < u + 9) // XXX: Only for !DATA frames - return (HTC_S_MORE); - return (HTC_S_COMPLETE); + + return (HTC_S_MORE); } /**********************************************************************/ From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:05 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:05 +0000 (UTC) Subject: [6.0] 1b9c650d2 h2: Fix a possible thread leak scenario Message-ID: <20180816085305.257899BBC7@lists.varnish-cache.org> commit 1b9c650d26f2b0c2ae706fbad9a9f302ebbb1ddc Author: Dag Haavi Finstad Date: Tue May 29 14:44:16 2018 +0200 h2: Fix a possible thread leak scenario If we have one or more streams set up because of a PRIORITY frame _and_ for some reason a tcp FIN is lost (or a client merely keeps a connection open), this transaction would be stalled indefinitely. diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 1bba9b332..2361c5e40 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -964,6 +964,7 @@ static int h2_sweep(struct worker *wrk, struct h2_sess *h2) { int tmo = 0; + int nprio = 0; struct h2_req *r2, *r22; ASSERT_RXTHR(h2); @@ -994,13 +995,21 @@ h2_sweep(struct worker *wrk, struct h2_sess *h2) continue; } break; + case H2_S_IDLE: + /* This stream was created from receiving a + * PRIORITY frame, and should not be counted + * as an active stream keeping the connection + * open. */ + AZ(r2->scheduled); + nprio++; + break; default: break; } } if (tmo) return (0); - return (h2->refcnt > 1); + return ((h2->refcnt - nprio) > 1); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:05 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:05 +0000 (UTC) Subject: [6.0] a1c641c35 Pass an h2_req arg to h2_tx_rst Message-ID: <20180816085305.5FD339BBE0@lists.varnish-cache.org> commit a1c641c356a02f7c8c936dfad6c04fcc061d0428 Author: Dag Haavi Finstad Date: Wed May 30 11:13:56 2018 +0200 Pass an h2_req arg to h2_tx_rst diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 2361c5e40..dc1212a7d 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -130,6 +130,31 @@ h2_connectionerror(uint32_t u) return (H2NN_ERROR); } +/**********************************************************************/ + +static h2_error +h2_tx_rst(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2, + uint32_t stream, h2_error h2e) +{ + h2_error ret; + char b[4]; + + CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC); + CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC); + + Lck_Lock(&h2->sess->mtx); + VSLb(h2->vsl, SLT_Debug, "H2: stream %u: %s", stream, h2e->txt); + Lck_Unlock(&h2->sess->mtx); + vbe32enc(b, h2e->val); + + H2_Send_Get(wrk, h2, r2); + ret = H2_Send_Frame(wrk, h2, H2_F_RST_STREAM, + 0, sizeof b, stream, b); + H2_Send_Rel(h2, r2); + + return (ret); +} + /********************************************************************** */ @@ -840,30 +865,6 @@ h2_frame_complete(struct http_conn *htc) /**********************************************************************/ -static h2_error -h2_tx_rst(struct worker *wrk, struct h2_sess *h2, - uint32_t stream, h2_error h2e) -{ - h2_error ret; - char b[4]; - - CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC); - - Lck_Lock(&h2->sess->mtx); - VSLb(h2->vsl, SLT_Debug, "H2: stream %u: %s", stream, h2e->txt); - Lck_Unlock(&h2->sess->mtx); - vbe32enc(b, h2e->val); - - H2_Send_Get(wrk, h2, h2->req0); - ret = H2_Send_Frame(wrk, h2, H2_F_RST_STREAM, - 0, sizeof b, stream, b); - H2_Send_Rel(h2, h2->req0); - - return (ret); -} - -/**********************************************************************/ - static h2_error h2_procframe(struct worker *wrk, struct h2_sess *h2, h2_frame h2f) @@ -904,7 +905,7 @@ h2_procframe(struct worker *wrk, struct h2_sess *h2, "H2: stream %u: Hit maximum number of " "concurrent streams", h2->rxf_stream); // rfc7540,l,1200,1205 - return (h2_tx_rst(wrk, h2, h2->rxf_stream, + return (h2_tx_rst(wrk, h2, h2->req0, h2->rxf_stream, H2SE_REFUSED_STREAM)); } h2->highest_stream = h2->rxf_stream; @@ -922,7 +923,7 @@ h2_procframe(struct worker *wrk, struct h2_sess *h2, if (h2->rxf_stream == 0 || h2e->connection) return (h2e); // Connection errors one level up - return (h2_tx_rst(wrk, h2, h2->rxf_stream, h2e)); + return (h2_tx_rst(wrk, h2, h2->req0, h2->rxf_stream, h2e)); } static int @@ -982,7 +983,7 @@ h2_sweep(struct worker *wrk, struct h2_sess *h2) break; case H2_S_CLOS_REM: if (!r2->scheduled) { - h2_tx_rst(wrk, h2, r2->stream, + h2_tx_rst(wrk, h2, h2->req0, r2->stream, H2SE_REFUSED_STREAM); h2_del_req(wrk, r2); continue; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:05 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:05 +0000 (UTC) Subject: [6.0] c0dc68441 Fix an h2 reqbody resource leak Message-ID: <20180816085305.88F4D9BBF8@lists.varnish-cache.org> commit c0dc68441efe89f25a86e12a72392278d5d0826b Author: Dag Haavi Finstad Date: Wed May 30 11:17:51 2018 +0200 Fix an h2 reqbody resource leak Properly shut down streams where we could not process a req body (e.g. via a failing cache_req_body). The rxthread may be waiting on this stream to consume a DATA frame - let it know before we go away to avoid it being stuck forever. diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index dc1212a7d..64d55a6f9 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -812,9 +812,34 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) return (retval); } +static void +h2_vfp_body_fini(struct vfp_ctx *vc, struct vfp_entry *vfe) +{ + struct h2_req *r2; + struct h2_sess *h2; + + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); + CAST_OBJ_NOTNULL(r2, vfe->priv1, H2_REQ_MAGIC); + CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC); + h2 = r2->h2sess; + + if (vc->failed) { + CHECK_OBJ_NOTNULL(r2->req->wrk, WORKER_MAGIC); + h2_tx_rst(r2->req->wrk, h2, r2, r2->stream, + H2SE_REFUSED_STREAM); + Lck_Lock(&h2->sess->mtx); + r2->error = H2SE_REFUSED_STREAM; + if (h2->mailcall == r2) + AZ(pthread_cond_signal(h2->cond)); + Lck_Unlock(&h2->sess->mtx); + } +} + static const struct vfp h2_body = { .name = "H2_BODY", .pull = h2_vfp_body, + .fini = h2_vfp_body_fini }; void v_matchproto_(vtr_req_body_t) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:05 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:05 +0000 (UTC) Subject: [6.0] 1350a400c make VRT_handling a no-op if no ctx->handling pointer Message-ID: <20180816085305.AC6E89BC08@lists.varnish-cache.org> commit 1350a400cbad6ce377812dacf1a3424c42765f05 Author: Nils Goroll Date: Wed May 30 12:57:44 2018 +0200 make VRT_handling a no-op if no ctx->handling pointer This is the case for the ctx created for director operations as first introduced with 5536f102b677e6b469f191fedab1c4cf51144e2c Alternatively, we could always set ctx->handling to some location with the same scope as the ctx, but as we are not inside VCL (and just happen to use the same context for simplicity and reusability of VRT/vmod functions), adding specific handling appears to be the cleaner solution. Fixes #2692 diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 6001d323b..433ffd02f 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -377,6 +377,8 @@ VRT_handling(VRT_CTX, unsigned hand) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (ctx->handling == NULL) + return; assert(hand > 0); assert(hand < VCL_RET_MAX); // XXX:NOTYET assert(*ctx->handling == 0); diff --git a/include/vrt.h b/include/vrt.h index 7939459b5..fdc454bba 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -177,7 +177,7 @@ struct vrt_ctx { unsigned syntax; unsigned method; - unsigned *handling; + unsigned *handling; // not in director context unsigned vclver; struct vsb *msg; // Only in ...init() From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:05 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:05 +0000 (UTC) Subject: [6.0] d90a2453b h2: Make sure an OU request ends up in half-closed state, not idle Message-ID: <20180816085305.CEAB89BC25@lists.varnish-cache.org> commit d90a2453bce793851404e4d9f0bc993409f8b507 Author: Dag Haavi Finstad Date: Thu May 31 14:21:55 2018 +0200 h2: Make sure an OU request ends up in half-closed state, not idle Ref: #2693 diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index b2ab70f96..b350f05c3 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -286,6 +286,7 @@ h2_ou_session(struct worker *wrk, struct h2_sess *h2, req->task.func = h2_do_req; req->task.priv = req; r2->scheduled = 1; + r2->state = H2_S_CLOS_REM; // rfc7540,l,489,491 req->err_code = 0; http_SetH(req->http, HTTP_HDR_PROTO, "HTTP/2.0"); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:06 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:06 +0000 (UTC) Subject: [6.0] 8e01e0d9b Drag the "Makefile.phk" experiment behind the barn and kill it. Message-ID: <20180816085306.1D79E9BC4B@lists.varnish-cache.org> commit 8e01e0d9b0e3e7098038561ccbc6046280cbe242 Author: Poul-Henning Kamp Date: Mon Jun 4 08:42:59 2018 +0000 Drag the "Makefile.phk" experiment behind the barn and kill it. diff --git a/Makefile.inc.phk b/Makefile.inc.phk deleted file mode 100644 index ba9202fdb..000000000 --- a/Makefile.inc.phk +++ /dev/null @@ -1,245 +0,0 @@ - -.PHONY: default -default: all - -WARNS ?= 1 - -.PHONY: depend all clean install test -depend all clean install test: - @$(MAKE) --no-print-directory -f Makefile.phk TGT=$@ real-$@ \ - $(shell env CC=$(CC) WARNS=$(WARNS) \ - sh ${TOPDIR}/config.phk $(TOPDIR) $(CURDIR) ) - -CFLAGS += $(CF_CFLAGS) $(CF_CWFLAGS) -CFLAGS += -I$(CURDIR) -CFLAGS += -I$(TOPDIR) -CFLAGS += -I$(TOPDIR)/include -CFLAGS += -I$(TOPDIR)/lib/libvgz -CFLAGS += -I/usr/local/include - -SHLIB_LDFLAGS += -shared -Wl,-x -Wl,--fatal-warnings -Wl,--warn-shared-textrel -VMOD_LDFLAGS += ${SHLIB_LDFLAGS} - -####################################################################### - -INSTALL_BASE ?= $(TOPDIR)/_install - -####################################################################### - -LIB_VARNISH = -L $(TOPDIR)/lib/libvarnish -lvarnish -LIB_VARNISHAPI = $(TOPDIR)/lib/libvarnishapi/libvarnishapi.a -LIB_VCC = -L $(TOPDIR)/lib/libvcc -lvcc -LIB_VGZ = -L $(TOPDIR)/lib/libvgz -lvgz -LIB_PCRE = -L /usr/local/lib -lpcre -LIB_EXECINFO = ${CFG_EXECINFO} -LIB_CURSES = -lcurses -LIB_READLINE = ${CFG_LINEDISC} - -####################################################################### -ifdef USE_THREADS -CFLAGS += -pthread -D_THREAD_SAFE -g -O2 -PROG_LDFLAGS += -pthread -D_THREAD_SAFE -g -O2 -endif - -ifdef USE_DLOPEN -PROG_LDFLAGS += -Wl,-E -PROG_LIBS += ${CFG_LIBDL} -endif - -####################################################################### -ifdef SUBDIRS -ifeq "$(findstring k,$(MAKEFLAGS))" "" - EOPT=set -e -else - EOPT=set +e -endif -define run-subdirs - $(EOPT) ; for dir in $(SUBDIRS); do \ - echo "->> $$dir $(@:real-%=%)" ; \ - $(MAKE) -C $$dir -f Makefile.phk $(@:real-%=%) ; \ - done -endef -else -define run-subdirs -endef -endif - -####################################################################### -ifdef NOWORK -ifdef SUBDIRS - -.PHONY: subdirs $(SUBDIRS) - -subdirs: $(SUBDIRS) - -$(SUBDIRS): - $(MAKE) -C $@ -f Makefile.phk $(@:real-%=%) - -TODO += subdirs -endif -endif - -####################################################################### -.SUFFIXES: .So -.c.So: - ${CC} $(CFLAGS) -fPIC -c $< -o $@ - - -####################################################################### - -TODO_DEPEND += $(MADE_FILES) -TODO_ALL += $(MADE_FILES) -CLEAN_FILES += $(MADE_FILES) - -MADE_SRC = $(filter %.c, $(MADE_FILES)) - -####################################################################### -ifdef PROG_SRC -PROGNAME = $(notdir $(CURDIR)) -MANNAME=$(PROGNAME).1 -TODO_DEPEND += _.depprog -TODO_ALL += $(PROGNAME) -TODO_INSTALL += prog_install -PROG_SRC += $(MADE_SRC) -PROG_OBJ = $(notdir $(PROG_SRC:.c=.o)) -CLEAN_FILES += $(PROGNAME) $(PROG_OBJ) _.depprog $(MANNAME) - -_.depprog: ${PROG_SRC} ${MADE_FILES} - $(CC) $(CFLAGS) -MM $^ > _.depprog - -ifeq ($(TGT), all) -include _.depprog -endif - -$(PROGNAME): $(PROG_OBJ) - $(CC) $(PROG_LDFLAGS) -o $(PROGNAME) $^ $(PROG_LIBS) $(LD_ADD) - -.PHONY: prog_install -prog_install: $(PROGNAME) - @cp $(PROGNAME) $(INSTALL_BASE)/bin/ - @[ ! -f $(MANNAME) ] || cp $(MANNAME) $(INSTALL_BASE)/man/ - -endif - -####################################################################### -ifdef SHLIB_SRC -SHLIBNAME = $(notdir $(CURDIR)) -TODO_ALL += $(SHLIBNAME).so -TODO_DEPEND += _.depshlib -TODO_INSTALL += shlib_install -SHLIB_SRC += $(MADE_SRC) -SHLIB_OBJ = $(notdir $(SHLIB_SRC:.c=.So)) -CLEAN_FILES += $(SHLIB_OBJ) $(SHLIBNAME).so _.depshlib - -_.depshlib: ${SHLIB_SRC} ${MADE_FILES} - $(CC) $(CFLAGS) -MM $^ |sed 's/o:/So:/' > _.depshlib - -ifeq ($(TGT), all) -include _.depshlib -endif - -$(SHLIBNAME).so: $(SHLIB_OBJ) - $(CC) $(SHLIB_LDFLAGS) -o $(SHLIBNAME).so $^ - -.PHONY: shlib_install -shlib_install: $(SHLIBNAME).so - @cp $(SHLIBNAME).so $(INSTALL_BASE)/lib/ - -endif - -####################################################################### -ifdef LIB_SRC -LIBNAME = $(notdir $(CURDIR)) -TODO_ALL += $(LIBNAME).a -TODO_DEPEND += _.deplib -LIB_SRC += $(MADE_SRC) -LIB_OBJ = $(notdir $(LIB_SRC:.c=.o)) -CLEAN_FILES += $(LIB_OBJ) $(LIBNAME).a _.deplib - -_.deplib: ${LIB_SRC} ${MADE_FILES} - $(CC) $(CFLAGS) -MM $^ > _.deplib - -ifeq ($(TGT), all) -include _.deplib -endif - -$(LIBNAME).a: $(LIB_OBJ) - $(AR) -rc $(LIBNAME).a $^ - ranlib $(LIBNAME).a - -endif - -####################################################################### -ifdef VMOD_SRC -#VMODNAME = $(subst libvmod_,,$(notdir $(CURDIR))) -VMODNAME = $(notdir $(CURDIR)) -TODO_ALL += vcc_if.h vcc_if.c $(VMODNAME).so -TODO_DEPEND += _.depvmod -TODO_INSTALL += vmod_install -VMOD_SRC += $(MADE_SRC) -VMOD_SRC += vcc_if.c -VMOD_OBJ = $(notdir $(VMOD_SRC:.c=.So)) -CLEAN_FILES += $(VMOD_OBJ) vcc_if.c vcc_if.h $(VMODNAME).so _.depvmod - -CFLAGS += -I$(TOPDIR)/bin/varnishd - -_.depvmod: ${VMOD_SRC} ${MADE_FILES} - $(CC) $(CFLAGS) -MM $^ |sed 's/o:/So:/' > _.depvmod - -ifeq ($(TGT), all) -include _.depvmod -endif - -vcc_if.c vcc_if.h: vmod.vcc $(TOPDIR)/lib/libvcc/vmodtool.py - ${PYTHON} $(TOPDIR)/lib/libvcc/vmodtool.py - -$(VMODNAME).so: $(VMOD_OBJ) - $(CC) $(VMOD_LDFLAGS) -o $(VMODNAME).so $^ - mkdir -p .libs - (cd .libs && ln -sf ../$(VMODNAME).so) - -.PHONY: vmod_install -vmod_install: $(VMODNAME).so - @cp $(VMODNAME).so $(INSTALL_BASE)/libexec/ - -endif - -####################################################################### -ifdef RST_MAN -ifdef HAVE_RST2HTML -TODO_ALL += ${MANNAME} - -${MANNAME}: ${RST_MAN} - rst2man ${RST_MAN} $(MANNAME) - -endif -endif - -####################################################################### - -.PHONY: real-depend -real-depend: $(TODO) $(TODO_DEPEND) - @$(run-subdirs) - @true - -.PHONY: real-all -real-all: $(TODO) $(TODO_ALL) - @$(run-subdirs) - @true - -.PHONY: real-clean -real-clean: $(TODO) $(TODO_CLEAN) - @$(run-subdirs) - @[ "x$(CLEAN_FILES)" = "x" ] || rm -f $(CLEAN_FILES) - -.PHONY: real-install -real-install: $(TODO_INSTALL) - @$(run-subdirs) - @true - -.PHONY: real-test -real-test: $(TODO_TEST) - @$(run-subdirs) - @true - -####################################################################### diff --git a/Makefile.phk b/Makefile.phk deleted file mode 100644 index afeeeb6c6..000000000 --- a/Makefile.phk +++ /dev/null @@ -1,14 +0,0 @@ -SUBDIRS = lib bin doc - -CLEAN_FILES += config.h include/vcs_version. include/vmod_abi.h _.cache - -TODO_INSTALL += top_install - -TOPDIR = $(CURDIR) -include $(TOPDIR)/Makefile.inc.phk - -.PHONY: top_install -top_install: - @for d in man doc etc bin lib libexec ; do \ - mkdir -p $(INSTALL_BASE)/$$d ; \ - done diff --git a/bin/Makefile.phk b/bin/Makefile.phk deleted file mode 100644 index 66816ffcc..000000000 --- a/bin/Makefile.phk +++ /dev/null @@ -1,11 +0,0 @@ -SUBDIRS += varnishadm -SUBDIRS += varnishd -SUBDIRS += varnishlog -SUBDIRS += varnishncsa -SUBDIRS += varnishtest -SUBDIRS += varnishstat -SUBDIRS += varnishhist -SUBDIRS += varnishtop - -TOPDIR = $(CURDIR)/.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/bin/varnishadm/Makefile.phk b/bin/varnishadm/Makefile.phk deleted file mode 100644 index 368b80a47..000000000 --- a/bin/varnishadm/Makefile.phk +++ /dev/null @@ -1,12 +0,0 @@ -PROG_SRC = varnishadm.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_PCRE} -LD_ADD += ${LIB_READLINE} -LD_ADD += -lm - -RST_MAN += $(TOPDIR)/doc/sphinx/reference/varnishadm.rst - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/bin/varnishd/Makefile.phk b/bin/varnishd/Makefile.phk deleted file mode 100644 index 6882faab3..000000000 --- a/bin/varnishd/Makefile.phk +++ /dev/null @@ -1,149 +0,0 @@ -VPATH += cache common mgt waiter storage hash http1 proxy - -PROG_SRC += cache/cache_acceptor.c -PROG_SRC += cache/cache_backend.c -PROG_SRC += cache/cache_backend_cfg.c -PROG_SRC += cache/cache_backend_tcp.c -PROG_SRC += cache/cache_backend_probe.c -PROG_SRC += cache/cache_ban.c -PROG_SRC += cache/cache_ban_build.c -PROG_SRC += cache/cache_ban_lurker.c -PROG_SRC += cache/cache_busyobj.c -PROG_SRC += cache/cache_cli.c -PROG_SRC += cache/cache_director.c -PROG_SRC += cache/cache_esi_deliver.c -PROG_SRC += cache/cache_esi_fetch.c -PROG_SRC += cache/cache_esi_parse.c -PROG_SRC += cache/cache_expire.c -PROG_SRC += cache/cache_fetch.c -PROG_SRC += cache/cache_fetch_proc.c -PROG_SRC += cache/cache_gzip.c -PROG_SRC += cache/cache_hash.c -PROG_SRC += cache/cache_http.c -PROG_SRC += http1/cache_http1_deliver.c -PROG_SRC += http1/cache_http1_fetch.c -PROG_SRC += http1/cache_http1_fsm.c -PROG_SRC += http1/cache_http1_proto.c -PROG_SRC += http1/cache_http1_pipe.c -PROG_SRC += http1/cache_http1_line.c -PROG_SRC += http1/cache_http1_vfp.c -PROG_SRC += cache/cache_lck.c -PROG_SRC += cache/cache_main.c -PROG_SRC += cache/cache_mempool.c -PROG_SRC += cache/cache_obj.c -PROG_SRC += cache/cache_panic.c -PROG_SRC += cache/cache_pool.c -PROG_SRC += cache/cache_range.c -PROG_SRC += cache/cache_req.c -PROG_SRC += cache/cache_req_fsm.c -PROG_SRC += cache/cache_req_body.c -PROG_SRC += cache/cache_rfc2616.c -PROG_SRC += cache/cache_session.c -PROG_SRC += cache/cache_shmlog.c -PROG_SRC += cache/cache_vary.c -PROG_SRC += cache/cache_vcl.c -PROG_SRC += cache/cache_vrt.c -PROG_SRC += cache/cache_vrt_re.c -PROG_SRC += cache/cache_vrt_var.c -PROG_SRC += cache/cache_vrt_vmod.c -PROG_SRC += cache/cache_vrt_priv.c -PROG_SRC += cache/cache_wrk.c -PROG_SRC += cache/cache_ws.c -PROG_SRC += cache/cache_deliver_proc.c - -PROG_SRC += proxy/cache_proxy_proto.c - -PROG_SRC += common/common_vsc.c -PROG_SRC += common/common_vsm.c - -PROG_SRC += hash/hash_classic.c -PROG_SRC += hash/hash_critbit.c -PROG_SRC += hash/mgt_hash.c -PROG_SRC += hash/hash_simple_list.c - -PROG_SRC += mgt/mgt_child.c -PROG_SRC += mgt/mgt_cli.c -PROG_SRC += mgt/mgt_main.c -PROG_SRC += mgt/mgt_param.c -PROG_SRC += mgt/mgt_param_bits.c -PROG_SRC += mgt/mgt_param_tbl.c -PROG_SRC += mgt/mgt_param_tcp.c -PROG_SRC += mgt/mgt_param_tweak.c -PROG_SRC += mgt/mgt_pool.c -PROG_SRC += mgt/mgt_jail.c -PROG_SRC += mgt/mgt_jail_unix.c -PROG_SRC += mgt/mgt_jail_solaris.c -PROG_SRC += mgt/mgt_shmem.c -PROG_SRC += mgt/mgt_vcc.c -PROG_SRC += mgt/mgt_vcl.c -PROG_SRC += mgt/mgt_acceptor.c - -PROG_SRC += storage/mgt_stevedore.c -PROG_SRC += storage/mgt_storage_persistent.c -PROG_SRC += storage/stevedore.c -PROG_SRC += storage/stevedore_utils.c -PROG_SRC += storage/storage_file.c -PROG_SRC += storage/storage_lru.c -PROG_SRC += storage/storage_malloc.c -PROG_SRC += storage/storage_persistent.c -PROG_SRC += storage/storage_persistent_silo.c -PROG_SRC += storage/storage_persistent_subr.c -PROG_SRC += storage/storage_simple.c -PROG_SRC += storage/storage_umem.c - -PROG_SRC += waiter/cache_waiter.c -PROG_SRC += waiter/cache_waiter_epoll.c -PROG_SRC += waiter/cache_waiter_kqueue.c -PROG_SRC += waiter/cache_waiter_poll.c -PROG_SRC += waiter/cache_waiter_ports.c -PROG_SRC += waiter/mgt_waiter.c - -USE_THREADS = YES -USE_DLOPEN = YES - -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_VCC} -LD_ADD += ${LIB_PCRE} -LD_ADD += ${LIB_EXECINFO} -LD_ADD += ${LIB_VGZ} -LD_ADD += -lm - -RST_MAN += $(TOPDIR)/doc/sphinx/reference/varnishd.rst - -MADE_FILES += builtin_vcl.h - -TODO_INSTALL += install_etc - -PARST=$(TOPDIR)/doc/sphinx/include/params.rst - -TODO_ALL += $(PARST) -CLEAN_FILES += $(PARST) - -CFLAGS += -DVARNISHD_IS_NOT_A_VMOD - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -$(PARST): $(PROGNAME) - -ls -l $(PARST) $(PROGNAME) - mkdir -p $(TOPDIR)/doc/sphinx/include - ./varnishd -x parameter > $(PARST) - -# -# Turn the builtin.vcl file into a C-string we can include in the program. -# -builtin_vcl.h: builtin.vcl - echo '/*' > $@ - echo ' * NB: This file is machine generated, DO NOT EDIT!' >> $@ - echo ' *' >> $@ - echo ' * Edit builtin.vcl instead and run make' >> $@ - echo ' *' >> $@ - echo ' */' >> $@ - echo '' >> $@ - sed -e 's/"/\\"/g' \ - -e 's/$$/\\n"/' \ - -e 's/^/ "/' builtin.vcl >> $@ - -.PHONY: install_etc -install_etc: builtin_vcl.h - @cp builtin_vcl.h $(INSTALL_BASE)/etc/ diff --git a/bin/varnishhist/Makefile.phk b/bin/varnishhist/Makefile.phk deleted file mode 100644 index c2df17fe6..000000000 --- a/bin/varnishhist/Makefile.phk +++ /dev/null @@ -1,9 +0,0 @@ -PROG_SRC = varnishhist.c -PROG_SRC += varnishhist_options.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += -lpthread -lncurses -lm ${LIB_PCRE} - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/bin/varnishlog/Makefile.phk b/bin/varnishlog/Makefile.phk deleted file mode 100644 index c02404623..000000000 --- a/bin/varnishlog/Makefile.phk +++ /dev/null @@ -1,14 +0,0 @@ -PROG_SRC = varnishlog.c -PROG_SRC = varnishlog_options.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_PCRE} -LD_ADD += -lm - -TODO_ALL += build_man - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -.PHONY: build_man diff --git a/bin/varnishncsa/Makefile.phk b/bin/varnishncsa/Makefile.phk deleted file mode 100644 index fd73e255d..000000000 --- a/bin/varnishncsa/Makefile.phk +++ /dev/null @@ -1,15 +0,0 @@ -PROG_SRC += base64.c -PROG_SRC += varnishncsa.c -PROG_SRC += varnishncsa_options.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_PCRE} -LD_ADD += -lm - -TODO_ALL += build_man - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -.PHONY: build_man diff --git a/bin/varnishstat/Makefile.phk b/bin/varnishstat/Makefile.phk deleted file mode 100644 index 3a89de7b9..000000000 --- a/bin/varnishstat/Makefile.phk +++ /dev/null @@ -1,13 +0,0 @@ -PROG_SRC += varnishstat.c -PROG_SRC += varnishstat_curses.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_PCRE} -LD_ADD += ${LIB_CURSES} -LD_ADD += -lm - -RST_MAN += $(TOPDIR)/doc/sphinx/reference/varnishstat.rst - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/bin/varnishtest/Makefile.phk b/bin/varnishtest/Makefile.phk deleted file mode 100644 index b406ccec4..000000000 --- a/bin/varnishtest/Makefile.phk +++ /dev/null @@ -1,31 +0,0 @@ -PROG_SRC += vtc.c -PROG_SRC += vtc_client.c -PROG_SRC += vtc_http.c -PROG_SRC += vtc_log.c -PROG_SRC += vtc_logexp.c -PROG_SRC += vtc_main.c -PROG_SRC += vtc_barrier.c -PROG_SRC += vtc_server.c -PROG_SRC += vtc_syslog.c -PROG_SRC += vtc_varnish.c -PROG_SRC += vtc_process.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_PCRE} -LD_ADD += ${LIB_VGZ} -LD_ADD += -lm - -USE_THREADS = yes - -RST_MAN += $(TOPDIR)/doc/sphinx/reference/varnishtest.rst - -TODO_TEST += all_tests - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -.PHONY: all_tests - -all_tests: - ./varnishtest -i -j 24 tests/*.vtc diff --git a/bin/varnishtop/Makefile.phk b/bin/varnishtop/Makefile.phk deleted file mode 100644 index 12d4de3e4..000000000 --- a/bin/varnishtop/Makefile.phk +++ /dev/null @@ -1,14 +0,0 @@ -PROG_SRC += varnishtop.c -PROG_SRC += varnishtop_options.c - -LD_ADD += ${LIB_VARNISHAPI} -LD_ADD += ${LIB_VARNISH} -LD_ADD += ${LIB_PCRE} -LD_ADD += -lm -lpthread -lncurses - -TODO_ALL += build_man - -TOPDIR = $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -.PHONY: build_man diff --git a/config.phk b/config.phk deleted file mode 100644 index 4111c35a5..000000000 --- a/config.phk +++ /dev/null @@ -1,303 +0,0 @@ -#!/bin/sh - -set -e - -####################################################################### -# Administrative settings - -ADM_PROJECT=varnish -ADM_VERSION=trunk - -CONFIG_H=phk_hack/config.h - -####################################################################### -# We always rebuild the config when make is run in the toplevel directory -# Otherwise, we try to use a cached config, if we have one. -# -# We know we're in the toplevel directory, because we get passed -# TOPDIR and CURDIR as arguments - -if [ "x$1" = "x" -o "x$2" = "x" ] ; then - echo "Missing arguments, assuming topdir" 1>&2 - set `pwd` `pwd` -fi - -if [ "x$1" = "x$2" ] ; then - rm -f _.cache -elif [ "x$1" != "x" -a -d $1 ] ; then - cd $1 -fi - -####################################################################### -# autocrap co-existence -# We put our config.h somewhere else and delete autocraps. -# Autocrap regenerates its own config.h and doesn't know about ours - -mkdir -p phk_hack -rm -f config.h - -####################################################################### - - -if [ -f _.cache -a -f ${CONFIG_H} ] ; then - cat _.cache - exit 0 -fi - -echo "Building Config" 1>&2 - -####################################################################### -# Look for #include files for HAVE_ etc. - -if true ; then - rm -f ${CONFIG_H}_ - echo '' > ${CONFIG_H}_ - - for i in \ - curses.h \ - endian.h \ - execinfo.h \ - ncurses.h \ - ncurses/curses.h \ - ncursesw.h \ - ncursesw/curses.h \ - priv.h \ - pthread_np.h \ - edit/readline/readline.h \ - readline/history.h \ - editline/readline.h \ - readline/readline.h \ - sys/endian.h \ - sys/filio.h \ - sys/mount.h \ - sys/statvfs.h \ - sys/vfs.h \ - umem.h - do - if [ -f /usr/include/$i ] ; then - n=`echo $i | tr '[a-z/.]' '[A-Z__]'` - echo "#define HAVE_$n 1" >> ${CONFIG_H}_ - else - echo "#include <$i>" > _.c - if cc -E _.c > /dev/null 2>& 1 ; then - n=`echo $i | tr '[a-z/.]' '[A-Z__]'` - echo "#define HAVE_$n 1" >> ${CONFIG_H}_ - fi - rm -f _.c - fi - done - echo "#define PACKAGE_TARNAME \"${ADM_PROJECT}\"" >> ${CONFIG_H}_ - echo "#define PACKAGE_VERSION \"${ADM_VERSION}\"" >> ${CONFIG_H}_ - - echo ' - #define VARNISH_VCL_DIR "/etc/varnish" - #define VARNISH_STATE_DIR "/tmp/phk/" - #define VARNISH_VMOD_DIR "/usr/lib/varnish/vmods" - ' >> ${CONFIG_H}_ - if [ ! -f ${CONFIG_H} ] ; then - mv ${CONFIG_H}_ ${CONFIG_H} - elif ! cmp -s ${CONFIG_H} ${CONFIG_H}_ ; then - mv ${CONFIG_H}_ ${CONFIG_H} - else - rm -f ${CONFIG_H}_ - fi -fi - -####################################################################### -# Create files depending on VCS (git) output - -VCSF=include/vcs_version.h -VMAV=include/vmod_abi.h -V=NOGIT - -if [ -d ./.git ] ; then - V=`git show -s --pretty=format:%h` -fi - -cat > ${VCSF}_ < ${VMAV} -fi - -####################################################################### -# Ask the compiler about stuff - -ask_compiler() { - a=`echo "$2" | - ${CC-cc} -E - -DWARNS=${WARNS-1} | - sed -e '/^#/d' -e '/^$/d' -e 's/"//g' -e 's/~/"/g' ` - echo "$1='" $a "'" >> _.cache -} - -# Warning flags -ask_compiler CF_CWFLAGS ' - #if WARNS >= 1 - "-Wall" - "-Werror" - #endif - #if WARNS >= 2 - "-W" - "-fstack-protector" - "-Wno-format-y2k" - "-Wstrict-prototypes" - "-Wmissing-prototypes" - "-Wpointer-arith" - "-Wreturn-type" - "-Wcast-qual" - "-Wwrite-strings" - "-Wswitch" - "-Wshadow" - "-Wunused-parameter" - "-Wcast-align" - "-Wchar-subscripts" - "-Winline" - "-Wnested-externs" - "-Wno-pointer-sign" - "-Wno-empty-body" - "-Wextra" - "-Wno-missing-field-initializers" - "-Wno-sign-compare" - #if defined(__clang__) - "-Wmissing-variable-declarations" - "-Wno-string-plus-int" - #endif - #endif - /* - * Write is marked with this on some Linux, and while that is - * well intentioned, they have implemented it so that the usual - * (void)bla; - * marker of intent does not work. - * I dont want to write bogo-code just to slip the best effort - * 4xx responses in cache_http1_fetch.c past the compiler. - */ - "-Wno-unused-result" - ' - -# Configuration options -ask_compiler CF_CFLAGS ' - #if defined(__SVR4) && defined(sun) - // Solaris and OmniOS - "-DHAVE_GETHRTIME" - "-DHAVE_PORT_CREATE" - "-DHAVE_SETPPRIV" - #endif - - #if !defined(__APPLE__) - "-DHAVE_DAEMON" - #endif - - // Where does this not work ? - "-DSO_SNDTIMEO_WORKS" - "-DSO_RCVTIMEO_WORKS" - "-DHAVE_TCP_KEEP" - - #if defined(__linux__) - "-D_GNU_SOURCE=1" - #endif - - "-DVCC_CC=~\~exec $(CC) -D_THREAD_SAFE -std=gnu99 -g " \ - "-O2 -Wall -Werror -pthread -fpic -shared -Wl,-x -o %o %s\~~" - - "-DVCC_WARNS=~\~$(CF_CWFLAGS)\~~" - - "-I$(TOPDIR)/phk_hack" - - ' - -####################################################################### -# Find a Python interpreter -# - -for i in 3.2 2.7 "" 2.5 2.6 3.0 3.1 -do - if python$i < /dev/null > /dev/null 2>&1 ; then - echo PYTHON=python$i >> _.cache - break - fi -done - -####################################################################### -# Find a rst2* tools -# - -if echo | rst2html > /dev/null 2>&1 ; then - echo "HAVE_RST2HTML=1" >> _.cache -fi - -####################################################################### -# Check for libedit - -if [ -f /usr/include/edit/readline/readline.h ] ; then - echo "CFG_LINEDISC=-ledit" >> _.cache -elif [ -f /usr/include/editline/readline.h ] ; then - echo "CFG_LINEDISC=-ledit" >> _.cache -elif [ -f /usr/include/readline/readline.h ] ; then - echo "CFG_LINEDISC=-lreadline" >> _.cache -else - echo "CFG_LINEDISC=" >> _.cache -fi - -####################################################################### -# Check for libexecinfo for FreeBSD::backtrace() - -if [ -f /usr/lib/libexecinfo.so ] ; then - echo "CFG_EXECINFO=-lexecinfo" >> _.cache -fi - -####################################################################### -# Check for libdl for Linux::dlopen() - -if [ `uname -s` = "Linux" ] ; then - echo "CFG_LIBDL=-ldl" >> _.cache -fi - -####################################################################### -# Done... -cat _.cache - -exit 0 - - -# HAVE_ACCEPT_FILTERS + -# HAVE_BACKTRACE + -# HAVE_CLOCK_GETTIME + -# HAVE_DAEMON + -# HAVE_KQUEUE + -# HAVE_NANOSLEEP + -# HAVE_PTHREAD_SET_NAME_NP + -# HAVE_PTHREAD_SETNAME_NP + -# HAVE_SETPROCTITLE + -# HAVE_SRANDOMDEV + -# HAVE_TCP_KEEP + -# HAVE_TIMEGM + -# PACKAGE_TARNAME + -# PACKAGE_VERSION + -# SO_RCVTIMEO_WORKS + -# SO_SNDTIMEO_WORKS + -# VCC_CC + -# HAVE_EPOLL_CTL - -# HAVE_LIBUMEM - -# USE_PCRE_JIT - -# _FILE_OFFSET_BITS - -# -# #echo 'CF_CFLAGS="-Wall"' diff --git a/doc/Makefile.phk b/doc/Makefile.phk deleted file mode 100644 index fe6059e95..000000000 --- a/doc/Makefile.phk +++ /dev/null @@ -1,7 +0,0 @@ - -ifdef HAVE_RST2HTML -SUBDIRS += sphinx -endif - -TOPDIR = .. -include $(TOPDIR)/Makefile.inc.phk diff --git a/doc/sphinx/Makefile.phk b/doc/sphinx/Makefile.phk deleted file mode 100644 index ba770753a..000000000 --- a/doc/sphinx/Makefile.phk +++ /dev/null @@ -1,239 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_elements.papersize=a4 -PAPEROPT_letter = -D latex_elements.papersize=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(CURDIR) - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -all: conf.py html - -conf.py: conf.py.in - cp conf.py.in conf.py - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -.PHONY: depend install test -depend install test: - @true - -clean: - -rm -rf $(BUILDDIR)/* conf.py - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Varnish.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Varnish.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -EXTRA_DIST = \ - conf.py \ - index.rst \ - glossary/index.rst \ - installation/bugs.rst \ - installation/help.rst \ - installation/index.rst \ - installation/install.rst \ - installation/platformnotes.rst \ - installation/prerequisites.rst \ - phk/autocrap.rst \ - phk/backends.rst \ - phk/barriers.rst \ - phk/gzip.rst \ - phk/http20.rst \ - phk/index.rst \ - phk/ipv6suckage.rst \ - phk/platforms.rst \ - phk/spdy.rst \ - phk/sphinx.rst \ - phk/ssl.rst \ - phk/thetoolsweworkwith.rst \ - phk/thoughts.rst \ - phk/three-zero.rst \ - phk/varnish_does_not_hash.rst \ - phk/vcl_expr.rst \ - phk/wanton_destruction.rst \ - reference/index.rst \ - reference/varnish-cli.rst \ - reference/varnishadm.rst \ - reference/varnishd.rst \ - reference/varnishhist.rst \ - reference/varnishlog.rst \ - reference/varnishncsa.rst \ - reference/varnishstat.rst \ - reference/varnishtest.rst \ - reference/varnishtop.rst \ - reference/vcl.rst \ - reference/vmod.rst \ - reference/vmod_std.rst \ - reference/vsl-query.rst \ - reference/vsl.rst \ - reference/vsm.rst \ - tutorial/backend_servers.rst \ - tutorial/index.rst \ - tutorial/introduction.rst \ - tutorial/now_what.rst \ - tutorial/peculiarities.rst \ - tutorial/putting_varnish_on_port_80.rst \ - tutorial/starting_varnish.rst \ - users-guide/command-line.rst \ - users-guide/compression.rst \ - users-guide/devicedetection.rst \ - users-guide/esi.rst \ - users-guide/increasing-your-hitrate.rst \ - users-guide/index.rst \ - users-guide/intro.rst \ - users-guide/operation-logging.rst \ - users-guide/operation-statistics.rst \ - users-guide/performance.rst \ - users-guide/purging.rst \ - users-guide/report.rst \ - users-guide/run_cli.rst \ - users-guide/run_security.rst \ - users-guide/running.rst \ - users-guide/sizing-your-cache.rst \ - users-guide/storage-backends.rst \ - users-guide/troubleshooting.rst \ - users-guide/vcl-actions.rst \ - users-guide/vcl-backends.rst \ - users-guide/vcl-built-in-subs.rst \ - users-guide/vcl-example-acls.rst \ - users-guide/vcl-example-manipulating-headers.rst \ - users-guide/vcl-example-manipulating-responses.rst \ - users-guide/vcl-example-websockets.rst \ - users-guide/vcl-examples.rst \ - users-guide/vcl-hashing.rst \ - users-guide/vcl-inline-c.rst \ - users-guide/vcl-saint-and-grace.rst \ - users-guide/vcl-syntax.rst \ - users-guide/vcl-variables.rst \ - users-guide/vcl.rst \ - include/params.rst \ - include/varnishncsa_options.rst \ - include/varnishncsa_synopsis.rst \ - include/varnishlog_options.rst \ - include/varnishlog_synopsis.rst \ - include/varnishtop_options.rst \ - include/varnishtop_synopsis.rst \ - include/varnishhist_options.rst \ - include/varnishhist_synopsis.rst \ - reference/vmod_std.generated.rst \ - reference/vmod_directors.generated.rst - - -dist-hook: - $(MAKE) html - cp -r $(BUILDDIR) $(distdir) - -distclean-local: - rm -rf $(BUILDDIR) - -# XXX: here be dragons -include/params.rst: ../../bin/varnishd/varnishd - ../../bin/varnishd/varnishd -x parameter > $@ - - -# only sphinx needs the opt2rst stuff anyway -%_opt2rst: ../../bin/%/%_options.h %_options.c - -include/varnishncsa_options.rst: varnishncsa - ../../bin/varnishncsa/varnishncsa --options > $@ - -include/varnishncsa_synopsis.rst: varnishncsa - ../../bin/varnishncsa/varnishncsa --synopsis > $@ - -include/varnishlog_options.rst: varnishlog - ../../bin/varnishlog/varnishlog --options > $@ - -include/varnishlog_synopsis.rst: varnishlog - ../../bin/varnishlog/varnishlog --synopsis > $@ - -include/varnishtop_options.rst: varnishtop - ../../bin/varnishtop/varnishtop --options > $@ - -include/varnishtop_synopsis.rst: varnishtop - ../../bin/varnishtop/varnishtop --synopsis > $@ - -include/varnishhist_options.rst: varnishhist - ./varnishhist --options > $@ - -include/varnishhist_synopsis.rst: varnishhist - ./varnishhist --synopsis > $@ - -reference/vmod_std.generated.rst: reference ../../lib/libvmod_std/vmod_std.rst - cp ../../lib/libvmod_std/vmod_std.rst $@ - -reference/vmod_directors.generated.rst: reference ../../lib/libvmod_directors/vmod_directors.rst - cp ../../lib/libvmod_directors/vmod_directors.rst $@ - diff --git a/lib/Makefile.phk b/lib/Makefile.phk deleted file mode 100644 index 86ea17279..000000000 --- a/lib/Makefile.phk +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = libvcc libvarnish libvarnishapi libvcc -SUBDIRS += libvgz -SUBDIRS += libvmod_debug libvmod_directors libvmod_std - -TOPDIR = $(CURDIR)/.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/lib/libvarnish/Makefile.phk b/lib/libvarnish/Makefile.phk deleted file mode 100644 index 501a35034..000000000 --- a/lib/libvarnish/Makefile.phk +++ /dev/null @@ -1,29 +0,0 @@ - -LIB_SRC += binary_heap.c -LIB_SRC += cli_auth.c -LIB_SRC += cli_common.c -LIB_SRC += cli_serve.c -LIB_SRC += vas.c -LIB_SRC += vav.c -LIB_SRC += vct.c -LIB_SRC += version.c -LIB_SRC += vev.c -LIB_SRC += vfil.c -LIB_SRC += vfl.c -LIB_SRC += vin.c -LIB_SRC += vlu.c -LIB_SRC += vmb.c -LIB_SRC += vnum.c -LIB_SRC += vpf.c -LIB_SRC += vre.c -LIB_SRC += vrnd.c -LIB_SRC += vsa.c -LIB_SRC += vsb.c -LIB_SRC += vsha256.c -LIB_SRC += vss.c -LIB_SRC += vsub.c -LIB_SRC += vtcp.c -LIB_SRC += vtim.c - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/lib/libvarnishapi/Makefile.phk b/lib/libvarnishapi/Makefile.phk deleted file mode 100644 index 3c4eca93f..000000000 --- a/lib/libvarnishapi/Makefile.phk +++ /dev/null @@ -1,38 +0,0 @@ - -LIB_SRC += vsc.c -LIB_SRC += vsl.c -LIB_SRC += vsl2rst.c -LIB_SRC += vsl_arg.c -LIB_SRC += vsl_cursor.c -LIB_SRC += vsl_dispatch.c -LIB_SRC += vsl_query.c -LIB_SRC += vsm.c -LIB_SRC += vut.c -LIB_SRC += vxp.c -LIB_SRC += vxp_fixed_token.c -LIB_SRC += vxp_lexer.c -LIB_SRC += vxp_parse.c - - -# We add more stuff to the SHLIB version to make it self-contained -SHLIB_SRC = $(LIB_SRC) -VPATH += ../libvarnish -SHLIB_SRC += vas.c -SHLIB_SRC += vav.c -SHLIB_SRC += vfl.c -SHLIB_SRC += vin.c -SHLIB_SRC += vpf.c -SHLIB_SRC += vre.c -SHLIB_SRC += vsb.c -SHLIB_SRC += vtim.c - -#LIB_SRC += vsl_glob_test.c -#LIB_SRC += vxp_test.c - -MADE_FILES += vxp_fixed_token.c vxp_tokens.h - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -$(MADE_FILES): generate.py - python generate.py diff --git a/lib/libvcc/Makefile.phk b/lib/libvcc/Makefile.phk deleted file mode 100644 index 333bad421..000000000 --- a/lib/libvcc/Makefile.phk +++ /dev/null @@ -1,25 +0,0 @@ - -LIB_SRC += vcc_acl.c -LIB_SRC += vcc_action.c -LIB_SRC += vcc_backend.c -LIB_SRC += vcc_backend_util.c -LIB_SRC += vcc_compile.c -LIB_SRC += vcc_expr.c -LIB_SRC += vcc_parse.c -LIB_SRC += vcc_storage.c -LIB_SRC += vcc_symb.c -LIB_SRC += vcc_token.c -LIB_SRC += vcc_utils.c -LIB_SRC += vcc_var.c -LIB_SRC += vcc_vmod.c -LIB_SRC += vcc_xref.c - -MADE_FILES += vcc_fixed_token.c vcc_obj.c vcc_token_defs.h - -CLEAN_FILES += $(MADE_FILES) - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - -$(MADE_FILES): generate.py - $(PYTHON) generate.py diff --git a/lib/libvgz/Makefile.phk b/lib/libvgz/Makefile.phk deleted file mode 100644 index b9383125a..000000000 --- a/lib/libvgz/Makefile.phk +++ /dev/null @@ -1,17 +0,0 @@ -LIB_SRC += adler32.c -LIB_SRC += compress.c -LIB_SRC += crc32.c -LIB_SRC += deflate.c -LIB_SRC += infback.c -LIB_SRC += inffast.c -LIB_SRC += inflate.c -LIB_SRC += inftrees.c -LIB_SRC += trees.c -LIB_SRC += uncompr.c -LIB_SRC += zutil.c - -CFLAGS += -DZLIB_CONST -D_LARGEFILE64_SOURCE=1 - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk - diff --git a/lib/libvmod_debug/Makefile.phk b/lib/libvmod_debug/Makefile.phk deleted file mode 100644 index 35135cbe0..000000000 --- a/lib/libvmod_debug/Makefile.phk +++ /dev/null @@ -1,7 +0,0 @@ - -VMOD_SRC += vmod_debug.c -VMOD_SRC += vmod_debug_obj.c -VMOD_SRC += vmod_debug_dyn.c - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/lib/libvmod_directors/Makefile.phk b/lib/libvmod_directors/Makefile.phk deleted file mode 100644 index bf0a9214d..000000000 --- a/lib/libvmod_directors/Makefile.phk +++ /dev/null @@ -1,9 +0,0 @@ - -VMOD_SRC += fall_back.c -VMOD_SRC += hash.c -VMOD_SRC += random.c -VMOD_SRC += round_robin.c -VMOD_SRC += vdir.c - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk diff --git a/lib/libvmod_std/Makefile.phk b/lib/libvmod_std/Makefile.phk deleted file mode 100644 index 376a6f0da..000000000 --- a/lib/libvmod_std/Makefile.phk +++ /dev/null @@ -1,8 +0,0 @@ - -VMOD_SRC += vmod_std.c -VMOD_SRC += vmod_std_conversions.c -VMOD_SRC += vmod_std_fileread.c -VMOD_SRC += vmod_std_querysort.c - -TOPDIR= $(CURDIR)/../.. -include $(TOPDIR)/Makefile.inc.phk From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:06 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:06 +0000 (UTC) Subject: [6.0] 9bf03910b Handle sigbus like sigsegv Message-ID: <20180816085306.42D889BC59@lists.varnish-cache.org> commit 9bf03910bf1a10d6a186427dfbd689e68e8502f4 Author: Nils Goroll Date: Mon Jun 4 14:01:15 2018 +0200 Handle sigbus like sigsegv For the purpose of our signal handler (and, in particular, the stack overflow detection heuristic) they are identical. Fixes #2695 (as confirmed by @lkarsten) diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index c77cca91b..8262e1e5e 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -243,9 +243,10 @@ child_signal_handler(int s, siginfo_t *si, void *c) memset(&sa, 0, sizeof sa); sa.sa_handler = SIG_DFL; (void)sigaction(SIGSEGV, &sa, NULL); + (void)sigaction(SIGBUS, &sa, NULL); (void)sigaction(SIGABRT, &sa, NULL); - while (s == SIGSEGV) { + while (s == SIGSEGV || s == SIGBUS) { req = THR_GetRequest(); if (req == NULL || req->wrk == NULL) break; diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc index f33a8bde6..09a9c1cd0 100644 --- a/bin/varnishtest/tests/c00057.vtc +++ b/bin/varnishtest/tests/c00057.vtc @@ -76,7 +76,7 @@ client c2 -connect ${v2_sock} { expect_close } -run -varnish v2 -cliexpect "Segmentation [fF]ault" "panic.show" +varnish v2 -cliexpect "[bB]us error|Segmentation [fF]ault" "panic.show" varnish v2 -cliok "panic.clear" From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:06 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:06 +0000 (UTC) Subject: [6.0] 5bf1397f0 vcp: move open calls to VCP function, use function pointers Message-ID: <20180816085306.674869BC62@lists.varnish-cache.org> commit 5bf1397f09ed72cc6268b55e61edd3c9438f2574 Author: Nils Goroll Date: Tue Jun 5 08:02:38 2018 +0200 vcp: move open calls to VCP function, use function pointers diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c index fd416e822..c92ba8cbb 100644 --- a/bin/varnishd/cache/cache_tcp_pool.c +++ b/bin/varnishd/cache/cache_tcp_pool.c @@ -368,6 +368,21 @@ VCP_Recycle(const struct worker *wrk, struct pfd **pfdp) } } +/*-------------------------------------------------------------------- + * Open a new connection from pool. + */ + +static int +VCP_Open(const struct conn_pool *cp, double tmo, const void **privp) +{ + int r; + + CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); + + r = cp->methods->open(cp, tmo, privp); + + return (r); +} /*-------------------------------------------------------------------- * Close a connection. @@ -406,7 +421,7 @@ VCP_Close(struct pfd **pfdp) } /*-------------------------------------------------------------------- - * Get a connection + * Get a connection, possibly recycled */ static struct pfd * @@ -444,7 +459,7 @@ VCP_Get(struct conn_pool *cp, double tmo, struct worker *wrk, INIT_OBJ(pfd->waited, WAITED_MAGIC); pfd->state = PFD_STATE_USED; pfd->conn_pool = cp; - pfd->fd = cp->methods->open(cp, tmo, &pfd->priv); + pfd->fd = VCP_Open(cp, tmo, &pfd->priv); if (pfd->fd < 0) { FREE_OBJ(pfd); Lck_Lock(&cp->mtx); @@ -718,17 +733,13 @@ VTP_Rel(struct tcp_pool **tpp) } /*-------------------------------------------------------------------- - * Open a new connection from pool. This is a distinct function since - * probing cannot use a recycled connection. + * Open a new connection from pool. */ int VTP_Open(const struct tcp_pool *tp, double tmo, const void **privp) { - - if (tp->uds != NULL) - return (vus_open(tp->cp, tmo, privp)); - return (vtp_open(tp->cp, tmo, privp)); + return (VCP_Open(tp->cp, tmo, privp)); } /*-------------------------------------------------------------------- From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:06 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:06 +0000 (UTC) Subject: [6.0] 8322b21c9 Be a bit less Postel-y about http header charactersets. Message-ID: <20180816085306.979269BC85@lists.varnish-cache.org> commit 8322b21c9ad8dfb352a3e28d0c946eaf8250c1d3 Author: Poul-Henning Kamp Date: Tue Jun 5 07:43:55 2018 +0000 Be a bit less Postel-y about http header charactersets. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index ad4421844..9d1c0727f 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -116,7 +116,7 @@ static uint16_t http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, unsigned maxhdr) { - char *q, *r; + char *q, *r, *s; assert(p > htc->rxbuf_b); assert(p <= htc->rxbuf_e); @@ -188,7 +188,14 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, q--; *q = '\0'; - if (strchr(p, ':') == NULL) { + for (s = p; *s != ':' && s < q; s++) { + if (!vct_istchar(*s)) { + VSLb(hp->vsl, SLT_BogoHeader, + "Illegal char 0x%02x in header name", *s); + return (400); + } + } + if (*s != ':') { VSLb(hp->vsl, SLT_BogoHeader, "Header without ':' %.*s", (int)(q - p > 20 ? 20 : q - p), p); return (400); @@ -204,18 +211,6 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, (int)(q - p > 20 ? 20 : q - p), p); return (400); } - - for (; p < q; p++) { - if (vct_islws(*p)) { - VSLb(hp->vsl, SLT_BogoHeader, - "Space in header '%.*s'", - (int)Tlen(hp->hd[hp->nhd - 1]), - hp->hd[hp->nhd - 1].b); - return (400); - } - if (*p == ':') - break; - } } if (p < htc->rxbuf_e) p += vct_skipcrlf(p); diff --git a/bin/varnishtest/tests/b00049.vtc b/bin/varnishtest/tests/b00049.vtc index 7d2e289d5..af3cac740 100644 --- a/bin/varnishtest/tests/b00049.vtc +++ b/bin/varnishtest/tests/b00049.vtc @@ -7,6 +7,11 @@ server s1 { varnish v1 -vcl+backend { } -start +logexpect l1 -v v1 -g raw { + expect * 1004 BogoHeader "Illegal char 0x20 in header name" + expect * 1006 BogoHeader "Illegal char 0x2f in header name" +} -start + client c1 { send "GET / HTTP/1.1\r\n" send "Host: foo\r\n" @@ -30,3 +35,14 @@ client c1 { rxresp expect resp.status == 400 } -run + +client c1 { + send "GET / HTTP/1.1\r\n" + send "Host: foo\r\n" + send "Accept/Encoding: gzip\r\n" + send "\r\n" + rxresp + expect resp.status == 400 +} -run + +logexpect l1 -wait From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:06 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:06 +0000 (UTC) Subject: [6.0] 07bf5d5cb Cover H2's illegal header detection code. Message-ID: <20180816085306.BBBA89BC92@lists.varnish-cache.org> commit 07bf5d5cb4d37a8ff62e941db3e6ea547549991b Author: Poul-Henning Kamp Date: Tue Jun 5 08:09:01 2018 +0000 Cover H2's illegal header detection code. diff --git a/bin/varnishtest/tests/t02002.vtc b/bin/varnishtest/tests/t02002.vtc index f2cfb50f8..c1652b1a5 100644 --- a/bin/varnishtest/tests/t02002.vtc +++ b/bin/varnishtest/tests/t02002.vtc @@ -40,3 +40,18 @@ varnish v1 -expect MEMPOOL.req0.live == 0 varnish v1 -expect MEMPOOL.req1.live == 0 varnish v1 -expect MEMPOOL.sess0.live == 0 varnish v1 -expect MEMPOOL.sess1.live == 0 + +client c1 { + stream 11 { + txreq -hdr sna[]fu foo.bar -pad cotton + rxrst + } -run +} -run + +client c1 { + stream 13 { + txreq -hdr snaFu foo.bar -pad cotton + rxrst + } -run +} -run + From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:06 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:06 +0000 (UTC) Subject: [6.0] 8f2a0d4cc Clear bo->was_304 on return(retry) Message-ID: <20180816085306.DEAE89BCA8@lists.varnish-cache.org> commit 8f2a0d4cc99c42229351c282e798080544883ed9 Author: Dag Haavi Finstad Date: Tue Jun 5 14:04:57 2018 +0200 Clear bo->was_304 on return(retry) Fixes: #2700 Conflicts: bin/varnishd/cache/cache_fetch.c diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index ee6091dab..6da9156b1 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -240,6 +240,7 @@ vbf_stp_retry(struct worker *wrk, struct busyobj *bo) bo->storage = NULL; bo->do_esi = 0; bo->do_stream = 1; + bo->was_304 = 0; // XXX: BereqEnd + BereqAcct ? VSL_ChgId(bo->vsl, "bereq", "retry", VXID_Get(wrk, VSL_BACKENDMARKER)); diff --git a/bin/varnishtest/tests/r02700.vtc b/bin/varnishtest/tests/r02700.vtc new file mode 100644 index 000000000..ca4598d21 --- /dev/null +++ b/bin/varnishtest/tests/r02700.vtc @@ -0,0 +1,47 @@ +varnishtest "#2700: IMS and return (retry)" + +server s1 { + rxreq + txresp -hdr {Etag: "foo"} -body "1" + + rxreq + expect req.http.If-None-Match == {"foo"} + expect req.http.retries == "0" + txresp -status 304 + + rxreq + expect req.http.retries == "1" + expect req.http.If-None-Match == {"foo"} + txresp -status 304 +} -start + + +varnish v1 -vcl+backend { + sub vcl_backend_fetch { + set bereq.http.retries = bereq.retries; + } + sub vcl_backend_response { + set beresp.ttl = 1ms; + set beresp.grace = 0s; + set beresp.keep = 1h; + + if (beresp.was_304 && bereq.retries == 0) { + return (retry); + } + + set beresp.http.was-304 = beresp.was_304; + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.was-304 == "false" + + delay 0.1 + + txreq + rxresp + expect resp.http.was-304 == "true" +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] b84afa939 A spot of FlexeLinting Message-ID: <20180816085307.0BC649BCB2@lists.varnish-cache.org> commit b84afa939a0532397926bccb7860b2b87c1ae964 Author: Poul-Henning Kamp Date: Wed Jun 6 06:31:14 2018 +0000 A spot of FlexeLinting diff --git a/bin/varnishtest/teken.c b/bin/varnishtest/teken.c index ad06c57c6..bf5f782ce 100644 --- a/bin/varnishtest/teken.c +++ b/bin/varnishtest/teken.c @@ -457,6 +457,8 @@ teken_state_numbers(teken_t *t, teken_char_t c) return (0); } +//lint -save -emacro((835),k,K) '|' has zero RHS + #define k TC_BLACK #define b TC_BLUE #define y TC_BROWN @@ -642,6 +644,8 @@ static const teken_color_t teken_256to16tab[] = { #undef R #undef W +//lint -restore + teken_color_t teken_256to8(teken_color_t c) { diff --git a/bin/varnishtest/teken_wcwidth.h b/bin/varnishtest/teken_wcwidth.h index 6482305e1..73401698f 100644 --- a/bin/varnishtest/teken_wcwidth.h +++ b/bin/varnishtest/teken_wcwidth.h @@ -104,7 +104,7 @@ static int teken_wcwidth(teken_char_t ucs) /* if we arrive here, ucs is not a combining or C0/C1 control character */ return 1 + - (ucs >= 0x1100 && + (int)(ucs >= 0x1100 && (ucs <= 0x115f || /* Hangul Jamo init. consonants */ ucs == 0x2329 || ucs == 0x232a || (ucs >= 0x2e80 && ucs <= 0xa4cf && diff --git a/bin/varnishtest/vtc_http2.c b/bin/varnishtest/vtc_http2.c index fccc8e35d..764710f35 100644 --- a/bin/varnishtest/vtc_http2.c +++ b/bin/varnishtest/vtc_http2.c @@ -77,6 +77,7 @@ enum h2_type { TYPE_MAX }; +//lint -save -e849 Same enum value enum { ACK = 0x1, END_STREAM = 0x1, @@ -84,6 +85,7 @@ enum { END_HEADERS = 0x4, PRIORITY = 0x20, }; +//lint -restore struct stream { unsigned magic; @@ -103,7 +105,7 @@ struct stream { VTAILQ_HEAD(, frame) fq; char *body; - int bodylen; + long bodylen; struct hpk_hdr req[MAX_HDR]; struct hpk_hdr resp[MAX_HDR]; @@ -868,7 +870,7 @@ do { \ #define RETURN_BUFFED(val) \ do { \ - snprintf(buf, 20, "%d", val); \ + snprintf(buf, 20, "%ld", (long)val); \ return (buf); \ } while (0) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] 81a43b629 Flexelinting Message-ID: <20180816085307.2CDF79BCBC@lists.varnish-cache.org> commit 81a43b629a5f7b58affc8c0088e2dacfb0632333 Author: Poul-Henning Kamp Date: Wed Jun 6 07:01:31 2018 +0000 Flexelinting diff --git a/lib/libvcc/flint.lnt b/lib/libvcc/flint.lnt index 7d7d60dcf..e6c7cbd75 100644 --- a/lib/libvcc/flint.lnt +++ b/lib/libvcc/flint.lnt @@ -3,3 +3,5 @@ -emacro(835, EXPR_VAR) // Info 835: A zero has been given as right argument to operator '<<' -esym(755, VCL_40) // Not used (right now) + +-esym(768, token) // FLINTBUG: global struct member 'token' not ref From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] 257328211 More flexelinting Message-ID: <20180816085307.511D69BCC7@lists.varnish-cache.org> commit 2573282114a34a010cad66abafec3c7b4d53aae7 Author: Poul-Henning Kamp Date: Wed Jun 6 07:25:32 2018 +0000 More flexelinting diff --git a/flint.lnt b/flint.lnt index a5859409a..1d2482b90 100644 --- a/flint.lnt +++ b/flint.lnt @@ -135,6 +135,11 @@ -esym(534, VSB_vprintf) -esym(534, VSB_putc) +/////////////////////////////////////////////////////////////////////// +// + +-emacro(801, VRB_*) // goto considered bad + /////////////////////////////////////////////////////////////////////// // diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index 5a0477053..1b1eb0194 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -254,9 +254,9 @@ VUT_Signaled(struct VUT *vut, int sig) { CHECK_OBJ_NOTNULL(vut, VUT_MAGIC); - vut->sighup |= (sig == SIGHUP); - vut->sigint |= (sig == SIGINT || sig == SIGTERM); - vut->sigusr1 |= (sig == SIGUSR1); + vut->sighup |= (int)(sig == SIGHUP); + vut->sigint |= (int)(sig == SIGINT || sig == SIGTERM); + vut->sigusr1 |= (int)(sig == SIGUSR1); } void From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] fa375cd51 More FlexeLintery Message-ID: <20180816085307.724B99BCD4@lists.varnish-cache.org> commit fa375cd51e480ddf9d075e858eae61236a1834ef Author: Poul-Henning Kamp Date: Wed Jun 6 07:48:28 2018 +0000 More FlexeLintery diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index 8bdb0651b..ba4b01e6b 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -76,12 +76,12 @@ struct top { double count; }; -static float period = 60; /* seconds */ +static int period = 60; /* seconds */ static unsigned ntop; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static int f_flag = 0; static unsigned maxfieldlen = 0; -static char *ident; +static const char *ident; static volatile sig_atomic_t end_of_file = 0; static volatile sig_atomic_t quit = 0; @@ -207,7 +207,7 @@ update(int p) int l, len, eof; double t = 0; static time_t last = 0; - static unsigned n; + static unsigned n = 0; const char *q; time_t now; diff --git a/flint.lnt b/flint.lnt index 1d2482b90..99dfe625c 100644 --- a/flint.lnt +++ b/flint.lnt @@ -139,6 +139,8 @@ // -emacro(801, VRB_*) // goto considered bad +-esym(534, *_VRB_REMOVE) // ignore retval +-esym(534, *_VRB_INSERT) // ignore retval /////////////////////////////////////////////////////////////////////// // diff --git a/lib/libvarnishapi/vut.c b/lib/libvarnishapi/vut.c index 1b1eb0194..03cd9f07a 100644 --- a/lib/libvarnishapi/vut.c +++ b/lib/libvarnishapi/vut.c @@ -275,7 +275,8 @@ VUT_Setup(struct VUT *vut) VUT_Error(vut, 1, "Only one of -n and -r options may be used"); /* Create and validate the query expression */ - vut->vslq = VSLQ_New(vut->vsl, NULL, vut->g_arg, vut->q_arg); + vut->vslq = VSLQ_New(vut->vsl, NULL, + (enum VSL_grouping_e)vut->g_arg, vut->q_arg); if (vut->vslq == NULL) VUT_Error(vut, 1, "Query expression error:\n%s", VSL_Error(vut->vsl)); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] 9a87f7dcb Whitespace OCD Message-ID: <20180816085307.9831D9BCEA@lists.varnish-cache.org> commit 9a87f7dcb1c463a27406b5c193fa0e68c3afcaa5 Author: Poul-Henning Kamp Date: Wed Jun 6 08:27:24 2018 +0000 Whitespace OCD diff --git a/bin/varnishtest/tests/r02700.vtc b/bin/varnishtest/tests/r02700.vtc index ca4598d21..68dd28fbc 100644 --- a/bin/varnishtest/tests/r02700.vtc +++ b/bin/varnishtest/tests/r02700.vtc @@ -30,7 +30,7 @@ varnish v1 -vcl+backend { } set beresp.http.was-304 = beresp.was_304; - } + } } -start client c1 { From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] ec663c719 Include a timestamp in all CLI JSON responses. Message-ID: <20180816085307.BE04D9BCFD@lists.varnish-cache.org> commit ec663c719bd0e42eaa9199935dd05697bddf3540 Author: Poul-Henning Kamp Date: Wed Jun 6 08:28:53 2018 +0000 Include a timestamp in all CLI JSON responses. Conflicts: bin/varnishd/cache/cache_director.c diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index b1084a162..de7ebdbd8 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -50,6 +50,7 @@ #include "vav.h" #include "vcli_serve.h" #include "vsb.h" +#include "vtim.h" struct VCLS_fd { unsigned magic; @@ -159,7 +160,7 @@ VCLS_func_help_json(struct cli *cli, const char * const *av, void *priv) cs = cli->cls; CHECK_OBJ_NOTNULL(cs, VCLS_MAGIC); - VCLI_JSON_begin(cli, 1, av); + VCLI_JSON_begin(cli, 2, av); VTAILQ_FOREACH(clp, &cs->funcs, list) { if (clp->auth > cli->auth) continue; @@ -674,7 +675,7 @@ VCLI_JSON_begin(struct cli *cli, unsigned ver, const char * const * av) if (av[i + 1] != NULL) VCLI_Out(cli, ", "); } - VCLI_Out(cli, "]"); + VCLI_Out(cli, "], %.3f", VTIM_real()); VSB_indent(cli->sb, 2); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:07 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:07 +0000 (UTC) Subject: [6.0] 53fa9ffac Fix copy&paste sloppyness in http_resp_size documentation Message-ID: <20180816085307.E63009BD10@lists.varnish-cache.org> commit 53fa9ffac5cb3d0541803b89077e318c410707d1 Author: Poul-Henning Kamp Date: Wed Jun 6 08:34:37 2018 +0000 Fix copy&paste sloppyness in http_resp_size documentation Fixes #2684 Reported by: ernestojpg at github diff --git a/include/tbl/params.h b/include/tbl/params.h index 8cfb7f0f3..e2ecff4c8 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -699,10 +699,10 @@ PARAM( /* s-text */ "Maximum number of bytes of HTTP backend response we will deal " "with. This is a limit on all bytes up to the double blank line " - "which ends the HTTP request.\n" - "The memory for the request is allocated from the backend workspace " + "which ends the HTTP response.\n" + "The memory for the response is allocated from the backend workspace " "(param: workspace_backend) and this parameter limits how much " - "of that the request is allowed to take up.", + "of that the response is allowed to take up.", /* l-text */ "", /* func */ NULL ) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:08 +0000 (UTC) Subject: [6.0] d25a5c6dd Remove spurios old prototype Message-ID: <20180816085308.1B97B9BD1F@lists.varnish-cache.org> commit d25a5c6dda60cf6ebd7f2db4c52b4e28f086ea64 Author: Poul-Henning Kamp Date: Wed Jun 6 12:55:14 2018 +0000 Remove spurios old prototype diff --git a/include/vfil.h b/include/vfil.h index 48d6f6215..25f3b3ac6 100644 --- a/include/vfil.h +++ b/include/vfil.h @@ -34,7 +34,6 @@ struct vfil_path; void VFIL_null_fd(int); -int seed_random(void); char *VFIL_readfile(const char *pfx, const char *fn, ssize_t *sz); int VFIL_writefile(const char *pfx, const char *fn, const char *buf, size_t sz); int VFIL_nonblocking(int fd); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:08 +0000 (UTC) Subject: [6.0] 660cdb6dd Use the string VRND for VSM segment names. Message-ID: <20180816085308.442D79BD2C@lists.varnish-cache.org> commit 660cdb6dd639bc9d766db002bdda54d04c471153 Author: Poul-Henning Kamp Date: Wed Jun 6 12:55:38 2018 +0000 Use the string VRND for VSM segment names. diff --git a/bin/varnishd/common/common_vsmw.c b/bin/varnishd/common/common_vsmw.c index 0aa5477e6..2c2337d80 100644 --- a/bin/varnishd/common/common_vsmw.c +++ b/bin/varnishd/common/common_vsmw.c @@ -151,13 +151,14 @@ static void vsmw_mkent(const struct vsmw *vsmw, const char *pfx) { int fd; + uint64_t rn; AN(pfx); while (1) { VSB_clear(vsmw->vsb); VSB_printf(vsmw->vsb, "_.%s", pfx); - VSB_printf(vsmw->vsb, ".%08lx", VRND_RandomTestable()); - VSB_printf(vsmw->vsb, "%08lx", VRND_RandomTestable()); + AZ(VRND_RandomCrypto(&rn, sizeof rn)); + VSB_printf(vsmw->vsb, ".%016jx", (uintmax_t)rn); AZ(VSB_finish(vsmw->vsb)); fd = openat(vsmw->vdirfd, VSB_data(vsmw->vsb), O_RDONLY); if (fd < 0 && errno == ENOENT) @@ -192,7 +193,7 @@ vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx) CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC); CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC); - VTAILQ_REMOVE(&vsmw->segs, seg, list); + TAILQ_REMOVE(&vsmw->segs, seg, list); REPLACE(seg->class, NULL); REPLACE(seg->id, NULL); FREE_OBJ(seg); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:08 +0000 (UTC) Subject: [6.0] c495cba6f Typo Message-ID: <20180816085308.6DB6B9BD42@lists.varnish-cache.org> commit c495cba6f30471b6b156b07673d66f239dfe131f Author: Poul-Henning Kamp Date: Wed Jun 6 12:59:05 2018 +0000 Typo diff --git a/bin/varnishd/common/common_vsmw.c b/bin/varnishd/common/common_vsmw.c index 2c2337d80..6d4545fc2 100644 --- a/bin/varnishd/common/common_vsmw.c +++ b/bin/varnishd/common/common_vsmw.c @@ -193,7 +193,7 @@ vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx) CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC); CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC); - TAILQ_REMOVE(&vsmw->segs, seg, list); + VTAILQ_REMOVE(&vsmw->segs, seg, list); REPLACE(seg->class, NULL); REPLACE(seg->id, NULL); FREE_OBJ(seg); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:08 +0000 (UTC) Subject: [6.0] 9e06cd754 Use strong VRND for silo unique number Message-ID: <20180816085308.BC5099BD6F@lists.varnish-cache.org> commit 9e06cd75482d455dd00f60f086b11ce8b76d52dc Author: Poul-Henning Kamp Date: Wed Jun 6 13:11:08 2018 +0000 Use strong VRND for silo unique number diff --git a/bin/varnishd/storage/storage_persistent_subr.c b/bin/varnishd/storage/storage_persistent_subr.c index 05ce65920..9f8d202af 100644 --- a/bin/varnishd/storage/storage_persistent_subr.c +++ b/bin/varnishd/storage/storage_persistent_subr.c @@ -45,6 +45,7 @@ #include "storage/storage.h" +#include "vrnd.h" #include "vsha256.h" #include "storage/storage_persistent.h" @@ -280,7 +281,7 @@ smp_newsilo(struct smp_sc *sc) assert(strlen(SMP_IDENT_STRING) < sizeof si->ident); /* Choose a new random number */ - sc->unique = random(); + AZ(VRND_RandomCrypto(&sc->unique, sizeof sc->unique)); smp_reset_sign(&sc->idn); si = sc->ident; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:08 +0000 (UTC) Subject: [6.0] a4a577941 Wrap the testable VRND in program supplied locking, because it is not thread-safe. Message-ID: <20180816085309.17FFB9BD8C@lists.varnish-cache.org> commit a4a577941d0ce5aa79487e59713113515077c64e Author: Poul-Henning Kamp Date: Wed Jun 6 13:42:51 2018 +0000 Wrap the testable VRND in program supplied locking, because it is not thread-safe. Switch from random(3) to testable VRND for same reason. diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c index acc110481..b1f993dbf 100644 --- a/bin/varnishd/cache/cache_esi_fetch.c +++ b/bin/varnishd/cache/cache_esi_fetch.c @@ -39,6 +39,8 @@ #include "cache_esi.h" +#include "vrnd.h" + /*--------------------------------------------------------------------- */ @@ -198,7 +200,7 @@ vfp_esi_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, *lp = 0; l = vef->ibuf_sz - (vef->ibuf_i - vef->ibuf); if (DO_DEBUG(DBG_ESI_CHOP)) { - d = (random() & 3) + 1; + d = (VRND_RandomTestable() & 3) + 1; if (d < l) l = d; } @@ -259,7 +261,7 @@ vfp_esi_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) AN(p); AN(lp); if (DO_DEBUG(DBG_ESI_CHOP)) { - d = (random() & 3) + 1; + d = (VRND_RandomTestable() & 3) + 1; if (d < *lp) *lp = d; } diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c index 8262e1e5e..c86db2887 100644 --- a/bin/varnishd/cache/cache_main.c +++ b/bin/varnishd/cache/cache_main.c @@ -52,6 +52,19 @@ volatile struct params *cache_param; +static pthread_mutex_t cache_vrnd_mtx; + +static void +cache_vrnd_lock(void) +{ + AZ(pthread_mutex_lock(&cache_vrnd_mtx)); +} + +static void +cache_vrnd_unlock(void) +{ + AZ(pthread_mutex_unlock(&cache_vrnd_mtx)); +} /*-------------------------------------------------------------------- * Per thread storage for the session currently being processed by @@ -339,6 +352,10 @@ child_main(int sigmagic, size_t altstksz) THR_SetName("cache-main"); + AZ(pthread_mutex_init(&cache_vrnd_mtx, NULL)); + VRND_Lock = cache_vrnd_lock; + VRND_Unlock = cache_vrnd_unlock; + VSM_Init(); /* First, LCK needs it. */ LCK_Init(); /* Second, locking */ diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c index 69b2d3db0..276566514 100644 --- a/bin/varnishtest/vtc.c +++ b/bin/varnishtest/vtc.c @@ -40,6 +40,7 @@ #include "vtc.h" #include "vav.h" +#include "vrnd.h" #include "vtim.h" #define MAX_TOKENS 200 @@ -50,6 +51,20 @@ pthread_t vtc_thread; int ign_unknown_macro = 0; static struct vtclog *vltop; +static pthread_mutex_t vtc_vrnd_mtx; + +static void +vtc_vrnd_lock(void) +{ + AZ(pthread_mutex_lock(&vtc_vrnd_mtx)); +} + +static void +vtc_vrnd_unlock(void) +{ + AZ(pthread_mutex_unlock(&vtc_vrnd_mtx)); +} + /********************************************************************** * Macro facility */ @@ -465,6 +480,11 @@ exec_file(const char *fn, const char *script, const char *tmpdir, (void)signal(SIGPIPE, SIG_IGN); + AZ(pthread_mutex_init(&vtc_vrnd_mtx, NULL)); + VRND_Lock = vtc_vrnd_lock; + VRND_Unlock = vtc_vrnd_unlock; + VRND_SeedAll(); + tfn = fn; vtc_loginit(logbuf, loglen); vltop = vtc_logopen("top"); diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 54b2a2097..741c5f12a 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -45,6 +45,7 @@ #include "vfil.h" #include "vgz.h" #include "vnum.h" +#include "vrnd.h" #include "vtcp.h" #include "hpack.h" @@ -189,7 +190,7 @@ synth_body(const char *len, int rnd) k = '!'; l = k; } else if (rnd) { - b[j] = (random() % 95) + ' '; + b[j] = (VRND_RandomTestable() % 95) + ' '; } else { b[j] = (char)l; if (++l == '~') @@ -1970,7 +1971,7 @@ xxx(void) *ibuf = 0; for (j = 0; j < 7; j++) { snprintf(strchr(ibuf, 0), 5, "%x", - (unsigned)random() & 0xffff); + (unsigned)VRND_RandomTestable() & 0xffff); vz.next_in = TRUST_ME(ibuf); vz.avail_in = strlen(ibuf); vz.next_out = TRUST_ME(obuf); diff --git a/include/vrnd.h b/include/vrnd.h index 6a8976292..a828af86b 100644 --- a/include/vrnd.h +++ b/include/vrnd.h @@ -28,7 +28,13 @@ * Random functions */ +typedef void vrnd_lock_f(void); + +extern vrnd_lock_f *VRND_Lock; +extern vrnd_lock_f *VRND_Unlock; + int VRND_RandomCrypto(void *, size_t); + long VRND_RandomTestable(void); double VRND_RandomTestableDouble(void); void VRND_SeedTestable(unsigned int); diff --git a/lib/libvarnish/binary_heap.c b/lib/libvarnish/binary_heap.c index b49f9d610..fee40c93c 100644 --- a/lib/libvarnish/binary_heap.c +++ b/lib/libvarnish/binary_heap.c @@ -519,6 +519,11 @@ chk2(struct binheap *bh) } #endif +static void +vrnd_lock(void) +{ +} + int main(void) { @@ -528,6 +533,9 @@ main(void) VRND_SeedAll(); VRND_SeedTestable(1); + VRND_Lock = vrnd_lock; + VRND_Unlock = vrnd_lock; + bh = binheap_new(NULL, cmp, update); for (n = 2; n; n += n) { child(bh, n - 1, &u, &v); diff --git a/lib/libvarnish/vrnd.c b/lib/libvarnish/vrnd.c index 3dc8b1855..13557b0e7 100644 --- a/lib/libvarnish/vrnd.c +++ b/lib/libvarnish/vrnd.c @@ -45,6 +45,10 @@ #include "vas.h" #include "vrnd.h" + +vrnd_lock_f *VRND_Lock; +vrnd_lock_f *VRND_Unlock; + /********************************************************************** * Stripped down random(3) implementation from FreeBSD, to provide * predicatable "random" numbers of testing purposes. @@ -96,23 +100,8 @@ good_rand(uint32_t ctx) return (x - 1); } -void -VRND_SeedTestable(unsigned int x) -{ - int i, lim; - - state[0] = (uint32_t)x; - for (i = 1; i < rand_deg; i++) - state[i] = good_rand(state[i - 1]); - fptr = &state[rand_sep]; - rptr = &state[0]; - lim = 10 * rand_deg; - for (i = 0; i < lim; i++) - (void)VRND_RandomTestable(); -} - -long -VRND_RandomTestable(void) +static long +vrnd_RandomTestable(void) { uint32_t i; uint32_t *f, *r; @@ -135,6 +124,35 @@ VRND_RandomTestable(void) return ((long)i); } + +void +VRND_SeedTestable(unsigned int x) +{ + int i, lim; + + state[0] = (uint32_t)x; + for (i = 1; i < rand_deg; i++) + state[i] = good_rand(state[i - 1]); + fptr = &state[rand_sep]; + rptr = &state[0]; + lim = 10 * rand_deg; + for (i = 0; i < lim; i++) + (void)vrnd_RandomTestable(); +} + +long +VRND_RandomTestable(void) +{ + long l; + + AN(VRND_Lock); + VRND_Lock(); + l = vrnd_RandomTestable(); + AN(VRND_Unlock); + VRND_Unlock(); + return (l); +} + double VRND_RandomTestableDouble(void) { From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:09 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:09 +0000 (UTC) Subject: [6.0] 4bffcce48 Fix a end-of-string mistake (spotted by FlexeLint) Message-ID: <20180816085309.4D4EE9BD9F@lists.varnish-cache.org> commit 4bffcce48c5e2cdc152c8c86e567298bd9ea8088 Author: Poul-Henning Kamp Date: Wed Jun 6 16:46:42 2018 +0000 Fix a end-of-string mistake (spotted by FlexeLint) diff --git a/bin/varnishncsa/varnishncsa.c b/bin/varnishncsa/varnishncsa.c index 488027d0e..c92b0a317 100644 --- a/bin/varnishncsa/varnishncsa.c +++ b/bin/varnishncsa/varnishncsa.c @@ -692,13 +692,12 @@ parse_format(const char *format) for (p = format; *p != '\0'; p++) { /* Allow the most essential escape sequences in format */ - if (*p == '\\') { - p++; - if (*p == 't') + if (*p == '\\' && p[1] != '\0') { + if (*++p == 't') AZ(VSB_putc(vsb, '\t')); else if (*p == 'n') AZ(VSB_putc(vsb, '\n')); - else if (*p != '\0') + else AZ(VSB_putc(vsb, *p)); continue; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:09 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:09 +0000 (UTC) Subject: [6.0] 021388ce3 Disable FlexeLint message 850, we think we know what we're doing in our loops. Message-ID: <20180816085309.73CEB9BDAB@lists.varnish-cache.org> commit 021388ce378830f7f446e4dfe6bf9ca46542dccc Author: Poul-Henning Kamp Date: Wed Jun 6 16:50:21 2018 +0000 Disable FlexeLint message 850, we think we know what we're doing in our loops. diff --git a/flint.lnt b/flint.lnt index 99dfe625c..a6c0737e4 100644 --- a/flint.lnt +++ b/flint.lnt @@ -49,6 +49,8 @@ -esym(818, argv) // Pointer parameter '...' could be declared as pointing to const +-e850 // loop variable modified in loop + /* * va_list's are opaque for a reason, but we pretend to FlexeLint that it * is just a void*, so it proposes constification, which is not generally OK, From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:09 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:09 +0000 (UTC) Subject: [6.0] af9110082 Supress Flexelints 835 from all macro expansions Message-ID: <20180816085309.9AD119BDCE@lists.varnish-cache.org> commit af9110082d45453008f22438a8fec001f118a3ff Author: Poul-Henning Kamp Date: Wed Jun 6 19:13:22 2018 +0000 Supress Flexelints 835 from all macro expansions diff --git a/bin/varnishtest/teken.c b/bin/varnishtest/teken.c index bf5f782ce..ad06c57c6 100644 --- a/bin/varnishtest/teken.c +++ b/bin/varnishtest/teken.c @@ -457,8 +457,6 @@ teken_state_numbers(teken_t *t, teken_char_t c) return (0); } -//lint -save -emacro((835),k,K) '|' has zero RHS - #define k TC_BLACK #define b TC_BLUE #define y TC_BROWN @@ -644,8 +642,6 @@ static const teken_color_t teken_256to16tab[] = { #undef R #undef W -//lint -restore - teken_color_t teken_256to8(teken_color_t c) { diff --git a/flint.lnt b/flint.lnt index a6c0737e4..0a9d6e9f0 100644 --- a/flint.lnt +++ b/flint.lnt @@ -5,6 +5,8 @@ //d__flexelint_v9__=1 +fan +-emacro((835),*) // A zero has been given as ___ argument to operator '___ + /////////////////////////////////////////////////////////////////////// // build/config related From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:09 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:09 +0000 (UTC) Subject: [6.0] 8dcb2cbe8 FlexeLinting Message-ID: <20180816085309.C19BA9BDDE@lists.varnish-cache.org> commit 8dcb2cbe810c979f25dea81da781f8debb3f7706 Author: Poul-Henning Kamp Date: Thu Jun 7 06:32:52 2018 +0000 FlexeLinting diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 6c72a655a..50e435679 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -68,7 +68,7 @@ static unsigned hist_buckets; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static int end_of_file = 0; -static double delay = 1; +static int ms_delay = 1000; static unsigned rr_hist[HIST_N]; static unsigned nhist; static unsigned next_hist; @@ -82,7 +82,7 @@ static pthread_cond_t timebend_cv; static double log_ten; static char *ident; -static const int scales[] = { +static const unsigned scales[] = { 1, 2, 3, @@ -103,7 +103,7 @@ static const int scales[] = { 25000, 50000, 100000, - INT_MAX + UINT_MAX }; struct profile { @@ -182,10 +182,10 @@ update(void) VTIM_format(vsl_ts, t); mvprintw(0, 0, "1:%u, n = %u, d = %g @ %s x %g", - scale, nhist, delay, t, timebend); + scale, nhist, 1e-3 * ms_delay, t, timebend); } else mvprintw(0, 0, "1:%u, n = %u, d = %g", - scale, nhist, delay); + scale, nhist, 1e-3 * ms_delay); for (j = 2; j < LINES - 3; j += 5) mvprintw(j, 0, "%u_", ((LINES - 3) - j) * scale); @@ -299,7 +299,7 @@ accumulate(struct VSL_data *vsl, struct VSL_transaction * const pt[], continue; /* select bucket */ - i = HIST_RES * (log(value) / log_ten); + i = HIST_RES * lround(log(value) / log_ten); if (i < hist_low * HIST_RES) i = hist_low * HIST_RES; if (i >= hist_high * HIST_RES) @@ -398,7 +398,8 @@ do_curses(void *arg) update(); AZ(pthread_mutex_unlock(&mtx)); - timeout(delay * 1000); + assert(ms_delay > 0); + timeout(ms_delay); switch ((ch = getch())) { case ERR: break; @@ -433,15 +434,15 @@ do_curses(void *arg) case '7': case '8': case '9': - delay = 1U << (ch - '0'); + ms_delay = 1U << (ch - '0'); break; case '+': - delay /= 2; - if (delay < 1e-3) - delay = 1e-3; + ms_delay /= 2; + if (ms_delay < 1) + ms_delay = 1; break; case '-': - delay *= 2; + ms_delay *= 2; break; case '>': case '<': @@ -520,8 +521,8 @@ main(int argc, char **argv) /* Usage help */ usage(0); case 'p': - delay = strtod(optarg, NULL); - if (delay <= 0) + ms_delay = lround(1e3 * strtod(optarg, NULL)); + if (ms_delay <= 0) VUT_Error(vut, 1, "-p: invalid '%s'", optarg); break; case 'P': @@ -571,7 +572,7 @@ main(int argc, char **argv) profile_error(optarg); cli_p.name = "custom"; - cli_p.tag = match_tag; + cli_p.tag = (enum VSL_tag_e)match_tag; cli_p.hist_low = -6; cli_p.hist_high = 3; profile = NULL; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:09 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:09 +0000 (UTC) Subject: [6.0] 62a778d90 Fix the Y-axis ticks. Message-ID: <20180816085309.E92B99BDFA@lists.varnish-cache.org> commit 62a778d90495aebd0471ea2214fa26ca43b984dd Author: Poul-Henning Kamp Date: Thu Jun 7 06:52:07 2018 +0000 Fix the Y-axis ticks. diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 50e435679..88ab59e8a 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -187,8 +187,8 @@ update(void) mvprintw(0, 0, "1:%u, n = %u, d = %g", scale, nhist, 1e-3 * ms_delay); - for (j = 2; j < LINES - 3; j += 5) - mvprintw(j, 0, "%u_", ((LINES - 3) - j) * scale); + for (j = 5; j < LINES - 2; j += 5) + mvprintw((LINES - 2) - j, 0, "%u_", j * scale); /* show them */ for (i = 0; i < n; ++i) { diff --git a/bin/varnishtest/tests/u00009.vtc b/bin/varnishtest/tests/u00009.vtc index 90b7a3dd6..77270fe92 100644 --- a/bin/varnishtest/tests/u00009.vtc +++ b/bin/varnishtest/tests/u00009.vtc @@ -20,4 +20,14 @@ client c1 { process p1 -expect-text 22 0 {#} +process p1 -expect-text 3 1 {20_} + +process p1 -screen_dump + +process p1 -winsz 23 80 + +delay 1.5 + +process p1 -expect-text 2 1 {20_} + process p1 -screen_dump -write {q} -wait From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:10 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:10 +0000 (UTC) Subject: [6.0] 0111c1083 More coverage. Message-ID: <20180816085310.1CEEA9BE0B@lists.varnish-cache.org> commit 0111c10833aefe8f1d4480c4470f14e23cf6e395 Author: Poul-Henning Kamp Date: Thu Jun 7 12:00:51 2018 +0000 More coverage. diff --git a/bin/varnishhist/varnishhist.c b/bin/varnishhist/varnishhist.c index 88ab59e8a..65f9246be 100644 --- a/bin/varnishhist/varnishhist.c +++ b/bin/varnishhist/varnishhist.c @@ -434,7 +434,7 @@ do_curses(void *arg) case '7': case '8': case '9': - ms_delay = 1U << (ch - '0'); + ms_delay = 1000U << (ch - '0'); break; case '+': ms_delay /= 2; diff --git a/bin/varnishtest/tests/u00009.vtc b/bin/varnishtest/tests/u00009.vtc index 77270fe92..060503c5b 100644 --- a/bin/varnishtest/tests/u00009.vtc +++ b/bin/varnishtest/tests/u00009.vtc @@ -26,6 +26,10 @@ process p1 -screen_dump process p1 -winsz 23 80 +delay 5 + +process p1 -write {0>+-<} + delay 1.5 process p1 -expect-text 2 1 {20_} From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:10 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:10 +0000 (UTC) Subject: [6.0] 977346eef Skip this test if asan is used Message-ID: <20180816085310.434F09BE1A@lists.varnish-cache.org> commit 977346eef2d6e697540c773f3a02c2ae95598482 Author: Federico G. Schwindt Date: Fri Jun 8 09:40:55 2018 +0100 Skip this test if asan is used diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc index 09a9c1cd0..ec90cc864 100644 --- a/bin/varnishtest/tests/c00057.vtc +++ b/bin/varnishtest/tests/c00057.vtc @@ -1,5 +1,7 @@ varnishtest "test sigsegv handler" +feature cmd "test -z $(env | grep ASAN_OPTIONS)" + server s1 { rxreq txresp From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:10 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:10 +0000 (UTC) Subject: [6.0] 568e6ec29 Add a comment for future reference Message-ID: <20180816085310.69F8F9BE2F@lists.varnish-cache.org> commit 568e6ec2946cb84d6209e483ae87994f5c20c27b Author: Federico G. Schwindt Date: Fri Jun 8 10:05:03 2018 +0100 Add a comment for future reference diff --git a/bin/varnishtest/tests/c00057.vtc b/bin/varnishtest/tests/c00057.vtc index ec90cc864..2b2f38891 100644 --- a/bin/varnishtest/tests/c00057.vtc +++ b/bin/varnishtest/tests/c00057.vtc @@ -1,5 +1,7 @@ varnishtest "test sigsegv handler" +# Under ASAN, the stack layout is different and STACK OVERFLOW is +# never printed. feature cmd "test -z $(env | grep ASAN_OPTIONS)" server s1 { From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:10 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:10 +0000 (UTC) Subject: [6.0] 7c3f06315 Fix PROXY and HTTP/1 proto dissectors to not rely on space for an extra NUL. Message-ID: <20180816085310.8E9D09BE48@lists.varnish-cache.org> commit 7c3f06315633280b4b43ed30038239947df02e05 Author: Poul-Henning Kamp Date: Fri Jun 8 16:41:15 2018 +0000 Fix PROXY and HTTP/1 proto dissectors to not rely on space for an extra NUL. diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index 9d1c0727f..d1ad4d28e 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -37,9 +37,6 @@ * and stops when we see the magic marker (double [CR]NL), and if we overshoot, * it keeps track of the "pipelined" data. * - * Until we see the magic marker, we have to keep the rxbuf NUL terminated - * because we use strchr(3) on it. - * * We use this both for client and backend connections. */ @@ -75,10 +72,6 @@ HTTP1_Complete(struct http_conn *htc) assert(htc->rxbuf_e >= htc->rxbuf_b); assert(htc->rxbuf_e <= htc->ws->r); - if (htc->rxbuf_e == htc->ws->r) - return (HTC_S_OVERFLOW); // No space for NUL - *htc->rxbuf_e = '\0'; - /* Skip any leading white space */ for (p = htc->rxbuf_b ; vct_islws(*p); p++) continue; @@ -95,12 +88,13 @@ HTTP1_Complete(struct http_conn *htc) * is completed. More stringent validation happens later. */ while (1) { - p = strchr(p, '\n'); + p = memchr(p, '\n', htc->rxbuf_e - p); if (p == NULL) return (HTC_S_MORE); - p++; - if (*p == '\r') - p++; + if (++p == htc->rxbuf_e) + return (HTC_S_MORE); + if (*p == '\r' && ++p == htc->rxbuf_e) + return (HTC_S_MORE); if (*p == '\n') break; } diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c index 32ddd6f61..a10756d24 100644 --- a/bin/varnishd/proxy/cache_proxy_proto.c +++ b/bin/varnishd/proxy/cache_proxy_proto.c @@ -69,13 +69,14 @@ vpx_proto1(const struct worker *wrk, const struct req *req) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); - q = strchr(req->htc->rxbuf_b, '\r'); + q = memchr(req->htc->rxbuf_b, '\r', + req->htc->rxbuf_e - req->htc->rxbuf_b); if (q == NULL) return (-1); *q++ = '\0'; /* Nuke the CRLF */ - if (*q != '\n') + if (*q != '\n' || q == req->htc->rxbuf_e) return (-1); *q++ = '\0'; @@ -515,8 +516,7 @@ vpx_complete(struct http_conn *htc) return (HTC_S_JUNK); if (j == 1 && i == sizeof vpx1_sig) { assert (htc->rxbuf_e < htc->ws->r); - *htc->rxbuf_e = '\0'; - q = strchr(p + i, '\n'); + q = memchr(p + i, '\n', htc->rxbuf_e - (p + i)); if (q != NULL && (q - htc->rxbuf_b) > 107) return (HTC_S_OVERFLOW); if (q == NULL) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:10 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:10 +0000 (UTC) Subject: [6.0] 8f4eed673 Whitespace OCD Message-ID: <20180816085310.B52D29BE62@lists.varnish-cache.org> commit 8f4eed673af6bc999836a35732a0a358f7c16515 Author: Federico G. Schwindt Date: Fri Jun 8 14:49:56 2018 +0100 Whitespace OCD diff --git a/bin/varnishtest/tests/u00009.vtc b/bin/varnishtest/tests/u00009.vtc index 060503c5b..5a3bf928b 100644 --- a/bin/varnishtest/tests/u00009.vtc +++ b/bin/varnishtest/tests/u00009.vtc @@ -22,7 +22,7 @@ process p1 -expect-text 22 0 {#} process p1 -expect-text 3 1 {20_} -process p1 -screen_dump +process p1 -screen_dump process p1 -winsz 23 80 diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index b7d81d459..05128ec21 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -328,7 +328,7 @@ class vcltype(object): self.c = ctype self.internal = internal vcltypes[name] = self - + vcltype("STRINGS", "void", True) vcltype("STRING_LIST", "void*", True) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:10 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:10 +0000 (UTC) Subject: [6.0] 103ea7c57 finalize task privs when rolling back workspaces Message-ID: <20180816085310.D98009BE77@lists.varnish-cache.org> commit 103ea7c573d153966db68763ce0b40d2e2c01554 Author: Nils Goroll Date: Sun Jun 10 10:07:29 2018 +0200 finalize task privs when rolling back workspaces ... and introduce request functions for this purpose (for busy objects, there is only one use case yet, so we don't). Before we reset the workspace, we must ensure that there are no active references to objects on it. As PRIV_TASK and PRIV_TOP have the same lifetime as the respective workspace, they need to be destroyed. vmods must not use workspaces for storing information referenced via any of the other PRIVs unless the rollback case is considered. Note that while this bug was exposed by beeaa19cced3fe1ab79381b2b1b7b0b5594cbb18, it existed all along for any vmod priv state stored on the workspace, so if a vmod happened to access a TASK_PRIV stored on the workspace, it would likely have triggered a magic check assertion as well. I got plans for making std.rollback() more useful. While this change is required to do so, it only partly covers the planned changes. Fixes #2706 diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index a6b9ee0b1..d741441ca 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -181,6 +181,28 @@ Req_Release(struct req *req) MPL_Free(pp->mpl_req, req); } +static void +req_finalize(struct req *req) +{ + VRTPRIV_dynamic_kill(req->privs, (uintptr_t)req); + VRTPRIV_dynamic_kill(req->privs, (uintptr_t)&req->top); + assert(VTAILQ_EMPTY(&req->privs->privs)); +} + +/*---------------------------------------------------------------------- + * TODO: + * - check for code duplication with cnt_recv_prep + * - re-check if complete + */ + +void +Req_Rollback(struct req *req) +{ + req_finalize(req); + HTTP_Copy(req->http, req->http0); + WS_Reset(req->ws, req->ws_req); +} + /*---------------------------------------------------------------------- * TODO: remove code duplication with cnt_recv_prep */ @@ -207,9 +229,7 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) req->vcl = NULL; } - VRTPRIV_dynamic_kill(req->privs, (uintptr_t)req); - VRTPRIV_dynamic_kill(req->privs, (uintptr_t)&req->top); - assert(VTAILQ_EMPTY(&req->privs->privs)); + req_finalize(req); /* Charge and log byte counters */ if (req->vsl->wid) { diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 00a02491b..b55a0c007 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -209,8 +209,8 @@ cnt_vclfail(const struct worker *wrk, struct req *req) AZ(req->objcore); AZ(req->stale_oc); - HTTP_Copy(req->http, req->http0); - WS_Reset(req->ws, req->ws_req); + Req_Rollback(req); + req->err_code = 503; req->err_reason = "VCL failed"; req->req_step = R_STP_SYNTH; @@ -857,8 +857,7 @@ cnt_recv(struct worker *wrk, struct req *req) VCL_recv_method(req->vcl, wrk, req, NULL, NULL); if (wrk->handling == VCL_RET_VCL && req->restarts == 0) { - HTTP_Copy(req->http, req->http0); - WS_Reset(req->ws, req->ws_req); + Req_Rollback(req); cnt_recv_prep(req, ci); VCL_recv_method(req->vcl, wrk, req, NULL, NULL); } diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 111c6530f..af122f768 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -314,6 +314,7 @@ void VRG_dorange(struct req *req, const char *r); /* cache_req.c */ struct req *Req_New(const struct worker *, struct sess *); void Req_Release(struct req *); +void Req_Rollback(struct req *req); void Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req); void Req_Fail(struct req *req, enum sess_close reason); void Req_AcctLogCharge(struct VSC_main *, struct req *); diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 433ffd02f..8a31ee157 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -519,10 +519,11 @@ VRT_Rollback(VRT_CTX, VCL_HTTP hp) CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); if (hp == ctx->http_req) { CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); - HTTP_Copy(ctx->req->http, ctx->req->http0); - WS_Reset(ctx->req->ws, ctx->req->ws_req); + Req_Rollback(ctx->req); } else if (hp == ctx->http_bereq) { CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); + // -> VBO_Rollback ? + VRTPRIV_dynamic_kill(ctx->bo->privs, (uintptr_t)ctx->bo); HTTP_Copy(ctx->bo->bereq, ctx->bo->bereq0); WS_Reset(ctx->bo->bereq->ws, ctx->bo->ws_bo); WS_Reset(ctx->bo->ws, ctx->bo->ws_bo); diff --git a/bin/varnishtest/tests/m00000.vtc b/bin/varnishtest/tests/m00000.vtc index 7bdaa02b1..5c0fa7536 100644 --- a/bin/varnishtest/tests/m00000.vtc +++ b/bin/varnishtest/tests/m00000.vtc @@ -16,7 +16,15 @@ varnish v1 -vcl+backend { debug.vsc_new(); } + sub vcl_synth { + set req.http.overwrite = "the workspace " + + "to ensure we notice any unfinished privs"; + } sub vcl_recv { + if (req.url == "/fail") { + debug.test_priv_task("foo"); + return (fail); + } debug.rot52(req); debug.vsc_count(); } @@ -52,6 +60,9 @@ client c1 { expect resp.http.encrypted == "ROT52" expect resp.http.what >= 16 expect resp.http.not == -1 + txreq -url "/fail" + rxresp + expect resp.status == 503 } -run varnish v1 -expect DEBUG.count == 1 From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:11 +0000 (UTC) Subject: [6.0] 4a0dcf40e Statistics for backend open errors Message-ID: <20180816085311.0AD459BE8E@lists.varnish-cache.org> commit 4a0dcf40e6813f1a569464315b8ad29469b607c9 Author: Nils Goroll Date: Tue Jun 5 08:04:14 2018 +0200 Statistics for backend open errors Previously, we had zero stats on the cause of backend connection errors, which made it close to impossible to diagnose such issues in retrospect (only via log mining). We now pass an optional backend vsc to vcp and record errors per backend. Open errors are really per vcp entry (ip + port or udc path), which can be shared amongst backends (and even vcls), but we maintain the counters per backend (and, consequently, per vcl) for simplicity. It should be noted though that errors for shared endpoints affect all backends using them. Ref #2622 Conflicts: bin/varnishd/cache/cache_backend.c diff --git a/bin/varnishd/VSC_vbe.vsc b/bin/varnishd/VSC_vbe.vsc index c5ca37f16..b21590965 100644 --- a/bin/varnishd/VSC_vbe.vsc +++ b/bin/varnishd/VSC_vbe.vsc @@ -78,5 +78,50 @@ :level: info :oneliner: Backend requests sent -.. varnish_vsc_end:: vbe +.. + === Anything below is actually per VCP entry, but collected per + === backend for simplicity + +.. varnish_vsc:: fail + :type: counter + :level: info + :oneliner: Connections failed + + Counter of failed opens. Detailed reasons are given in the + fail_* counters (DIAG level) and in Debug VSL. + + This counter is the sum of all detailed fail_* counters. + + All fail_* counters may be slightly inaccurate for efficiency. + +.. varnish_vsc:: fail_eacces + :type: counter + :level: diag + :oneliner: Connections failed with EACCES or EPERM + +.. varnish_vsc:: fail_eaddrnotavail + :type: counter + :level: diag + :oneliner: Connections failed with EADDRNOTAVAIL + +.. varnish_vsc:: fail_econnrefused + :type: counter + :level: diag + :oneliner: Connections failed with ECONNREFUSED + +.. varnish_vsc:: fail_enetunreach + :type: counter + :level: diag + :oneliner: Connections failed with ENETUNREACH +.. varnish_vsc:: fail_etimedout + :type: counter + :level: diag + :oneliner: Connections failed ETIMEDOUT + +.. varnish_vsc:: fail_other + :type: counter + :level: diag + :oneliner: Connections failed for other reason + +.. varnish_vsc_end:: vbe diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 610132a62..11856b8ca 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -114,7 +114,7 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo, bo->htc->doclose = SC_NULL; FIND_TMO(connect_timeout, tmod, bo, bp); - pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh); + pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh, bp->vsc); if (pfd == NULL) { VSLb(bo->vsl, SLT_FetchError, "backend %s: fail errno %d (%s)", diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 276391dba..b45eed1f6 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -276,7 +276,8 @@ vbp_poke(struct vbp_target *vt) t_start = t_now = VTIM_real(); t_end = t_start + vt->timeout; - s = VTP_Open(vt->tcp_pool, t_end - t_now, (const void **)&sa); + s = VTP_Open(vt->tcp_pool, t_end - t_now, (const void **)&sa, + vt->backend->vsc); if (s < 0) { /* Got no connection: failed */ return; diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c index c92ba8cbb..f5fa2a365 100644 --- a/bin/varnishd/cache/cache_tcp_pool.c +++ b/bin/varnishd/cache/cache_tcp_pool.c @@ -45,6 +45,8 @@ #include "cache_tcp_pool.h" #include "cache_pool.h" +#include "VSC_vbe.h" + struct conn_pool; /*-------------------------------------------------------------------- @@ -373,7 +375,8 @@ VCP_Recycle(const struct worker *wrk, struct pfd **pfdp) */ static int -VCP_Open(const struct conn_pool *cp, double tmo, const void **privp) +VCP_Open(const struct conn_pool *cp, double tmo, const void **privp, + struct VSC_vbe *vsc) { int r; @@ -381,6 +384,32 @@ VCP_Open(const struct conn_pool *cp, double tmo, const void **privp) r = cp->methods->open(cp, tmo, privp); + if (r >= 0 || vsc == NULL) + return (r); + + /* stats access unprotected */ + switch (errno) { + case EACCES: + case EPERM: + vsc->fail_eacces++; + break; + case EADDRNOTAVAIL: + vsc->fail_eaddrnotavail++; + break; + case ECONNREFUSED: + vsc->fail_econnrefused++; + break; + case ENETUNREACH: + vsc->fail_enetunreach++; + break; + case ETIMEDOUT: + vsc->fail_etimedout++; + break; + default: + vsc->fail_other++; + } + vsc->fail++; + return (r); } @@ -426,7 +455,7 @@ VCP_Close(struct pfd **pfdp) static struct pfd * VCP_Get(struct conn_pool *cp, double tmo, struct worker *wrk, - unsigned force_fresh) + unsigned force_fresh, struct VSC_vbe *vsc) { struct pfd *pfd; @@ -459,7 +488,7 @@ VCP_Get(struct conn_pool *cp, double tmo, struct worker *wrk, INIT_OBJ(pfd->waited, WAITED_MAGIC); pfd->state = PFD_STATE_USED; pfd->conn_pool = cp; - pfd->fd = VCP_Open(cp, tmo, &pfd->priv); + pfd->fd = VCP_Open(cp, tmo, &pfd->priv, vsc); if (pfd->fd < 0) { FREE_OBJ(pfd); Lck_Lock(&cp->mtx); @@ -737,9 +766,10 @@ VTP_Rel(struct tcp_pool **tpp) */ int -VTP_Open(const struct tcp_pool *tp, double tmo, const void **privp) +VTP_Open(const struct tcp_pool *tp, double tmo, const void **privp, + struct VSC_vbe *vsc) { - return (VCP_Open(tp->cp, tmo, privp)); + return (VCP_Open(tp->cp, tmo, privp, vsc)); } /*-------------------------------------------------------------------- @@ -770,10 +800,10 @@ VTP_Close(struct pfd **pfdp) struct pfd * VTP_Get(struct tcp_pool *tp, double tmo, struct worker *wrk, - unsigned force_fresh) + unsigned force_fresh, struct VSC_vbe *vsc) { - return VCP_Get(tp->cp, tmo, wrk, force_fresh); + return VCP_Get(tp->cp, tmo, wrk, force_fresh, vsc); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_tcp_pool.h b/bin/varnishd/cache/cache_tcp_pool.h index d554a360f..88b131e9a 100644 --- a/bin/varnishd/cache/cache_tcp_pool.h +++ b/bin/varnishd/cache/cache_tcp_pool.h @@ -50,6 +50,8 @@ void PFD_RemoteName(const struct pfd *, char *, unsigned, char *, unsigned); * Prototypes */ +struct VSC_vbe; + struct tcp_pool *VTP_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6, const char *uds, const void *id); /* @@ -70,9 +72,11 @@ void VTP_Rel(struct tcp_pool **); * the pool is destroyed and all cached connections closed. */ -int VTP_Open(const struct tcp_pool *, double tmo, const void **); +int VTP_Open(const struct tcp_pool *, double tmo, const void **, + struct VSC_vbe *); /* * Open a new connection and return the adress used. + * Errors will be accounted in the optional vsc */ void VTP_Close(struct pfd **); @@ -86,9 +90,10 @@ void VTP_Recycle(const struct worker *, struct pfd **); */ struct pfd *VTP_Get(struct tcp_pool *, double tmo, struct worker *, - unsigned force_fresh); + unsigned force_fresh, struct VSC_vbe *); /* * Get a (possibly) recycled connection. + * Open errors will be accounted in the optional vsc */ int VTP_Wait(struct worker *, struct pfd *, double tmo); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:11 +0000 (UTC) Subject: [6.0] 02b7e718f holddown times for certain backend connection errors Message-ID: <20180816085311.2E48C9BE98@lists.varnish-cache.org> commit 02b7e718f4616978b6e1f66ffa4f53948c74f0d4 Author: Nils Goroll Date: Tue Jun 5 10:13:44 2018 +0200 holddown times for certain backend connection errors This is similar to the vca pace: Depending on the backend connection error, it does not make sense to re-try in rapid succession, instead not attempting the failed connection again for some time will save resources both locally and remotely, where applicable, and should thus help improve the overall situation. Fixes #2622 diff --git a/bin/varnishd/VSC_vbe.vsc b/bin/varnishd/VSC_vbe.vsc index b21590965..5212119cd 100644 --- a/bin/varnishd/VSC_vbe.vsc +++ b/bin/varnishd/VSC_vbe.vsc @@ -124,4 +124,13 @@ :level: diag :oneliner: Connections failed for other reason +.. varnish_vsc:: helddown + :type: counter + :level: diag + :oneliner: Connection opens not attempted + + Connections not attempted during the backend_local_error_holddown + or backend_remote_error_holddown interval after a fundamental + connection issue. + .. varnish_vsc_end:: vbe diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c index f5fa2a365..d79273586 100644 --- a/bin/varnishd/cache/cache_tcp_pool.c +++ b/bin/varnishd/cache/cache_tcp_pool.c @@ -101,6 +101,9 @@ struct conn_pool { int n_kill; int n_used; + + double holddown; + int holddown_errno; }; struct tcp_pool { @@ -238,6 +241,7 @@ VCP_New(struct conn_pool *cp, const void *id, void *priv, cp->priv = priv; cp->methods = cm; cp->refcnt = 1; + cp->holddown = 0; Lck_New(&cp->mtx, lck_tcp_pool); VTAILQ_INIT(&cp->connlist); VTAILQ_INIT(&cp->killlist); @@ -375,32 +379,59 @@ VCP_Recycle(const struct worker *wrk, struct pfd **pfdp) */ static int -VCP_Open(const struct conn_pool *cp, double tmo, const void **privp, +VCP_Open(struct conn_pool *cp, double tmo, const void **privp, struct VSC_vbe *vsc) { int r; + double h; CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); + while (cp->holddown > 0) { + Lck_Lock(&cp->mtx); + if (cp->holddown == 0) { + Lck_Unlock(&cp->mtx); + break; + } + + if (VTIM_mono() >= cp->holddown) { + cp->holddown = 0; + Lck_Unlock(&cp->mtx); + break; + } + + if (vsc) + vsc->helddown++; + errno = cp->holddown_errno; + Lck_Unlock(&cp->mtx); + return (-1); + } + r = cp->methods->open(cp, tmo, privp); if (r >= 0 || vsc == NULL) return (r); + h = 0; + /* stats access unprotected */ switch (errno) { case EACCES: case EPERM: vsc->fail_eacces++; + h = cache_param->backend_local_error_holddown; break; case EADDRNOTAVAIL: vsc->fail_eaddrnotavail++; + h = cache_param->backend_local_error_holddown; break; case ECONNREFUSED: vsc->fail_econnrefused++; + h = cache_param->backend_remote_error_holddown; break; case ENETUNREACH: vsc->fail_enetunreach++; + h = cache_param->backend_remote_error_holddown; break; case ETIMEDOUT: vsc->fail_etimedout++; @@ -410,6 +441,18 @@ VCP_Open(const struct conn_pool *cp, double tmo, const void **privp, } vsc->fail++; + if (h == 0) + return (r); + + Lck_Lock(&cp->mtx); + h += VTIM_mono(); + if (cp->holddown == 0 || h < cp->holddown) { + cp->holddown = h; + cp->holddown_errno = errno; + } + + Lck_Unlock(&cp->mtx); + return (r); } @@ -766,7 +809,7 @@ VTP_Rel(struct tcp_pool **tpp) */ int -VTP_Open(const struct tcp_pool *tp, double tmo, const void **privp, +VTP_Open(struct tcp_pool *tp, double tmo, const void **privp, struct VSC_vbe *vsc) { return (VCP_Open(tp->cp, tmo, privp, vsc)); diff --git a/bin/varnishd/cache/cache_tcp_pool.h b/bin/varnishd/cache/cache_tcp_pool.h index 88b131e9a..9f640da73 100644 --- a/bin/varnishd/cache/cache_tcp_pool.h +++ b/bin/varnishd/cache/cache_tcp_pool.h @@ -72,7 +72,7 @@ void VTP_Rel(struct tcp_pool **); * the pool is destroyed and all cached connections closed. */ -int VTP_Open(const struct tcp_pool *, double tmo, const void **, +int VTP_Open(struct tcp_pool *, double tmo, const void **, struct VSC_vbe *); /* * Open a new connection and return the adress used. diff --git a/include/tbl/params.h b/include/tbl/params.h index e2ecff4c8..054b2f449 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -285,6 +285,45 @@ PARAM( /* func */ NULL ) +PARAM( + /* name */ backend_local_error_holddown, + /* typ */ timeout, + /* min */ "0.000", + /* max */ NULL, + /* default */ "10.000", + /* units */ "seconds", + /* flags */ EXPERIMENTAL, + /* s-text */ + "When connecting to backends, certain error codes " + "(EADDRNOTAVAIL, EACCESS, EPERM) signal a local resource shortage " + "or configuration issue for which retrying connection attempts " + "may worsen the situation due to the complexity of the operations " + "involved in the kernel.\n" + "This parameter prevents repeated connection attempts for the " + "configured duration.", + /* l-text */ "", + /* func */ NULL +) + +PARAM( + /* name */ backend_remote_error_holddown, + /* typ */ timeout, + /* min */ "0.000", + /* max */ NULL, + /* default */ "0.250", + /* units */ "seconds", + /* flags */ EXPERIMENTAL, + /* s-text */ + "When connecting to backends, certain error codes (ECONNREFUSED, " + "ENETUNREACH) signal fundamental connection issues such as the backend " + "not accepting connections or routing problems for which repeated " + "connection attempts are considered useless\n" + "This parameter prevents repeated connection attempts for the " + "configured duration.", + /* l-text */ "", + /* func */ NULL +) + PARAM( /* name */ cli_limit, /* typ */ bytes_u, From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:11 +0000 (UTC) Subject: [6.0] 32c5de647 add the long missing per-backend busy and unhealthy counters Message-ID: <20180816085311.5308A9BEAE@lists.varnish-cache.org> commit 32c5de6475e47f66f2e9e02fd71463b47ca50f2c Author: Nils Goroll Date: Tue Jun 5 10:51:45 2018 +0200 add the long missing per-backend busy and unhealthy counters Conflicts: bin/varnishd/cache/cache_backend.c diff --git a/bin/varnishd/VSC_vbe.vsc b/bin/varnishd/VSC_vbe.vsc index 5212119cd..cc0559831 100644 --- a/bin/varnishd/VSC_vbe.vsc +++ b/bin/varnishd/VSC_vbe.vsc @@ -78,6 +78,18 @@ :level: info :oneliner: Backend requests sent +.. varnish_vsc:: unhealthy + :type: counter + :level: info + :oneliner: Fetches not attempted due to backend being unhealthy + +.. varnish_vsc:: busy + :type: counter + :level: info + :oneliner: Fetches not attempted due to backend being busy + + Number of times the max_connections limit was reached + .. === Anything below is actually per VCP entry, but collected per === backend for simplicity diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 11856b8ca..a727f5ec8 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -91,7 +91,7 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo, if (!VDI_Healthy(bp->director, NULL)) { VSLb(bo->vsl, SLT_FetchError, "backend %s: unhealthy", bp->director->display_name); - // XXX: per backend stats ? + bp->vsc->unhealthy++; VSC_C_main->backend_unhealthy++; return (NULL); } @@ -99,7 +99,7 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo, if (bp->max_connections > 0 && bp->n_conn >= bp->max_connections) { VSLb(bo->vsl, SLT_FetchError, "backend %s: busy", bp->director->display_name); - // XXX: per backend stats ? + bp->vsc->busy++; VSC_C_main->backend_busy++; return (NULL); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:11 +0000 (UTC) Subject: [6.0] 46d1ad5c2 Backend_health: report error details Message-ID: <20180816085311.76EA49BEBC@lists.varnish-cache.org> commit 46d1ad5c29de427964beac84446a1e1bb3971fbb Author: Nils Goroll Date: Mon Jun 11 13:55:01 2018 +0200 Backend_health: report error details Previously, tracing the root cause of probe failures was unnecessarily complicated by the fact that the probe window bits and timing information were the only source of information when no HTTP status line was logged and for the case of all the bits being zero, almost impossible (e.g. differentiating between a local and remote connection open failure). We now re-use the response field for failing probes also. diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index b45eed1f6..3f3a106ba 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -39,6 +39,8 @@ #include #include +#include +#include #include #include "cache_varnishd.h" @@ -227,8 +229,15 @@ vbp_write(struct vbp_target *vt, int *sock, const void *buf, size_t len) i = write(*sock, buf, len); if (i != len) { - if (i < 0) + if (i < 0) { vt->err_xmit |= 1; + bprintf(vt->resp_buf, "Write error %d (%s)", + errno, strerror(errno)); + } else { + bprintf(vt->resp_buf, + "Short write (%d/%zu) error %d (%s)", + i, len, errno, strerror(errno)); + } VTCP_close(sock); return (-1); } @@ -279,7 +288,8 @@ vbp_poke(struct vbp_target *vt) s = VTP_Open(vt->tcp_pool, t_end - t_now, (const void **)&sa, vt->backend->vsc); if (s < 0) { - /* Got no connection: failed */ + bprintf(vt->resp_buf, "Open error %d (%s)", + errno, strerror(errno)); return; } @@ -296,7 +306,9 @@ vbp_poke(struct vbp_target *vt) t_now = VTIM_real(); tmo = (int)round((t_end - t_now) * 1e3); if (tmo <= 0) { - /* Spent too long time getting it */ + bprintf(vt->resp_buf, + "Open timeout %.3fs exceeded by %.3fs", + vt->timeout, t_now - t_end); VTCP_close(&s); return; } @@ -308,8 +320,10 @@ vbp_poke(struct vbp_target *vt) proxy_header = -1; Lck_Unlock(&vbp_mtx); - if (proxy_header < 0) + if (proxy_header < 0) { + bprintf(vt->resp_buf, "%s", "No backend"); return; + } /* Send the PROXY header */ assert(proxy_header <= 2); @@ -333,9 +347,17 @@ vbp_poke(struct vbp_target *vt) tmo = (int)round((t_end - t_now) * 1e3); if (tmo > 0) i = poll(pfd, 1, tmo); - if (i == 0 || tmo <= 0) { - if (i == 0) - vt->err_recv |= 1; + if (i == 0) { + vt->err_recv |= 1; + bprintf(vt->resp_buf, "Poll error %d (%s)", + errno, strerror(errno)); + VTCP_close(&s); + return; + } + if (tmo <= 0) { + bprintf(vt->resp_buf, + "Poll (read) timeout %.3fs exceeded by %.3fs", + vt->timeout, t_now - t_end); VTCP_close(&s); return; } @@ -344,20 +366,27 @@ vbp_poke(struct vbp_target *vt) sizeof vt->resp_buf - rlen); else i = read(s, buf, sizeof buf); - if (i <= 0) + if (i <= 0) { + if (i < 0) + bprintf(vt->resp_buf, "Read error %d (%s)", + errno, strerror(errno)); break; + } rlen += i; } VTCP_close(&s); if (i < 0) { + /* errno reported above */ vt->err_recv |= 1; return; } - if (rlen == 0) + if (rlen == 0) { + bprintf(vt->resp_buf, "%s", "Empty response"); return; + } /* So we have a good receive ... */ t_now = VTIM_real(); diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index fa348b39f..ac93f15b7 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -389,7 +389,7 @@ SLTM(Backend_health, 0, "Backend health check", "The format is::\n\n" "\t%s %s %s %u %u %u %f %f %s\n" "\t| | | | | | | | |\n" - "\t| | | | | | | | +- Probe HTTP response\n" + "\t| | | | | | | | +- Probe HTTP response / error information\n" "\t| | | | | | | +---- Average response time\n" "\t| | | | | | +------- Response time\n" "\t| | | | | +---------- Probe window size\n" From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:11 +0000 (UTC) Subject: [6.0] 5601a4cc6 Fixups from 'Fix PROXY and HTTP/1 proto dissectors' Message-ID: <20180816085311.A1B329BEE2@lists.varnish-cache.org> commit 5601a4cc63c6a92ca4fd76ac92359e619cd0cd84 Author: Martin Blix Grydeland Date: Mon Jun 11 14:33:26 2018 +0200 Fixups from 'Fix PROXY and HTTP/1 proto dissectors' Remove old and now invalid assert. Change order of evaluation in if-statement to make sure we don't step outside rxbuf_e. diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c index a10756d24..fc4c451b3 100644 --- a/bin/varnishd/proxy/cache_proxy_proto.c +++ b/bin/varnishd/proxy/cache_proxy_proto.c @@ -76,7 +76,7 @@ vpx_proto1(const struct worker *wrk, const struct req *req) *q++ = '\0'; /* Nuke the CRLF */ - if (*q != '\n' || q == req->htc->rxbuf_e) + if (q == req->htc->rxbuf_e || *q != '\n') return (-1); *q++ = '\0'; @@ -515,7 +515,6 @@ vpx_complete(struct http_conn *htc) if (j == 0) return (HTC_S_JUNK); if (j == 1 && i == sizeof vpx1_sig) { - assert (htc->rxbuf_e < htc->ws->r); q = memchr(p + i, '\n', htc->rxbuf_e - (p + i)); if (q != NULL && (q - htc->rxbuf_b) > 107) return (HTC_S_OVERFLOW); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:11 +0000 (UTC) Subject: [6.0] a61b713d2 New fix for #2285 and #2624 Message-ID: <20180816085311.D36A39BEF2@lists.varnish-cache.org> commit a61b713d2533cb0473eeebeb4fb72d3c100c38a9 Author: Martin Blix Grydeland Date: Tue Jun 5 17:02:55 2018 +0200 New fix for #2285 and #2624 Previous fix for #2285 (and the duplicate #2624) was missdiagnosed. The problem stems from a wrong assumption that the number of bytes already pipelined will be less than maxbytes, with maxbytes beeing the maximum number of bytes the HTC_RxStuff may need to get a full work unit. That assumption may fail during the H/1 to H/2 upgrade path where maxbytes change with the context, or during runtime changing of parameters. This patch makes HTC_RxStuff not assert if the pipelined data turned out to exceed maxbytes, but return overflow if we run out of workspace. (#2624 has received a workaround in the H/2 code that perhaps should be reverted). diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index a6c8f8378..0500bcef2 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -239,6 +239,11 @@ HTC_RxPipeline(struct http_conn *htc, void *p) /*---------------------------------------------------------------------- * Receive a request/packet/whatever, with timeouts * + * maxbytes is the maximum number of bytes the caller expects to need to + * reach a complete work unit. Note that due to pipelining the actual + * number of bytes passed to func in htc->rxbuf_b through htc->rxbuf_e may + * be larger. + * * t0 is when we start * *t1 becomes time of first non-idle rx * *t2 becomes time of complete rx @@ -261,6 +266,7 @@ HTC_RxStuff(struct http_conn *htc, htc_complete_f *func, AN(htc->ws->r); AN(htc->rxbuf_b); assert(htc->rxbuf_b <= htc->rxbuf_e); + assert(htc->rxbuf_e <= htc->ws->r); AZ(isnan(tn)); if (t1 != NULL) @@ -273,7 +279,7 @@ HTC_RxStuff(struct http_conn *htc, htc_complete_f *func, } z = (htc->ws->r - htc->rxbuf_b); if (z < maxbytes) - maxbytes = z; + maxbytes = z; /* Cap maxbytes at available WS */ while (1) { now = VTIM_real(); @@ -308,8 +314,9 @@ HTC_RxStuff(struct http_conn *htc, htc_complete_f *func, if (!isnan(ti) && ti < tn && hs == HTC_S_EMPTY) tmo = ti - now; z = maxbytes - (htc->rxbuf_e - htc->rxbuf_b); - assert(z >= 0); - if (z == 0) { + if (z <= 0) { + /* maxbytes reached but not HTC_S_COMPLETE. Return + * overflow. */ WS_ReleaseP(htc->ws, htc->rxbuf_b); return (HTC_S_OVERFLOW); } diff --git a/bin/varnishtest/tests/r02219.vtc b/bin/varnishtest/tests/r02219.vtc index 7187abc79..ff1a924f7 100644 --- a/bin/varnishtest/tests/r02219.vtc +++ b/bin/varnishtest/tests/r02219.vtc @@ -5,6 +5,8 @@ server s1 { txresp rxreq txresp + rxreq + txresp } -start varnish v1 -arg "-p workspace_client=9k" -proto PROXY -vcl+backend { @@ -59,3 +61,8 @@ client c2 { } rxresp } -run + +client c3 { + send "PROXY TCP4 127.0.0.1 127.0.0.1 1111 2222\r\nGET /CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC HTTP/1.1\r\n\r\n" + rxresp +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 264d0d934 New take on #2624 after Martin's RxStuff overflow fixes Message-ID: <20180816085312.0581C9BF16@lists.varnish-cache.org> commit 264d0d934241ce33837ac6c7c76ecb2107b830f9 Author: Dag Haavi Finstad Date: Tue Jun 12 11:28:59 2018 +0200 New take on #2624 after Martin's RxStuff overflow fixes diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 64d55a6f9..c43a65f96 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -882,8 +882,6 @@ h2_frame_complete(struct http_conn *htc) u = vbe32dec(htc->rxbuf_b) >> 8; if (l >= u + 9) return (HTC_S_COMPLETE); - else if (l > h2->local_settings.max_frame_size + 9) - return (HTC_S_OVERFLOW); return (HTC_S_MORE); } @@ -1068,7 +1066,7 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2) hs = HTC_RxStuff(h2->htc, h2_frame_complete, NULL, NULL, NAN, h2->sess->t_idle + cache_param->timeout_idle, - 16384 + 9); // rfc7540,l,4228,4228 + h2->local_settings.max_frame_size + 9); switch (hs) { case HTC_S_COMPLETE: break; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 6676a61ee Add asserts to ensure the (hypothetical?) race in #2528 doesn't happen. Message-ID: <20180816085312.2FB009BF24@lists.varnish-cache.org> commit 6676a61eec1a6de1a036083a89cc6423a87bc58b Author: Poul-Henning Kamp Date: Wed Jun 13 07:35:00 2018 +0000 Add asserts to ensure the (hypothetical?) race in #2528 doesn't happen. diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 6da9156b1..552e3e35e 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -903,6 +903,10 @@ vbf_fetch_thread(struct worker *wrk, void *priv) while (stp != F_STP_DONE) { CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); assert(bo->fetch_objcore->boc->refcount >= 1); + if (bo->fetch_objcore->boc->state < BOS_REQ_DONE) + AN(bo->req); + else + AZ(bo->req); switch (stp) { #define FETCH_STEP(l, U, arg) \ case F_STP_##U: \ From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 4e50978ee Add missing VTCP_Close() Message-ID: <20180816085312.548F39BF3C@lists.varnish-cache.org> commit 4e50978ee356a48714d17d5ec332d10748dada06 Author: Poul-Henning Kamp Date: Wed Jun 13 10:02:28 2018 +0000 Add missing VTCP_Close() diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 3f3a106ba..4945b8efd 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -322,6 +322,7 @@ vbp_poke(struct vbp_target *vt) if (proxy_header < 0) { bprintf(vt->resp_buf, "%s", "No backend"); + VTCP_close(&s); return; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 4c2f0d9b9 Remember to set the REQ_DONE state when we unset the bereq.body; Message-ID: <20180816085312.7AE3D9BF4B@lists.varnish-cache.org> commit 4c2f0d9b9008aca9aea7eb7d3c80fc7b51066b6c Author: Poul-Henning Kamp Date: Wed Jun 13 16:50:55 2018 +0000 Remember to set the REQ_DONE state when we unset the bereq.body; Found by: fgs & ASAN diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 76b4c89f9..c06dde561 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -500,6 +500,8 @@ VRT_u_bereq_body(VRT_CTX) if (ctx->bo->req != NULL) { CHECK_OBJ_NOTNULL(ctx->bo->req, REQ_MAGIC); ctx->bo->req = NULL; + ObjSetState(ctx->bo->wrk, + ctx->bo->fetch_objcore, BOS_REQ_DONE); http_Unset(ctx->bo->bereq, H_Content_Length); } } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 5f071e807 Add JSON ping output Message-ID: <20180816085312.A007D9BF6D@lists.varnish-cache.org> commit 5f071e8070ea9f6721dee670a21ab73eafe8ee87 Author: Lucas Guardalben Date: Wed May 16 15:52:17 2018 +0100 Add JSON ping output This adds -j support to the command varnishadm ping -j Tested on RFC4627/RFC7159/ECMA404 standards (all valid JSON) Conflicts: bin/varnishtest/tests/b00008.vtc diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c index bdaa4ae33..35dac06a6 100644 --- a/bin/varnishd/cache/cache_cli.c +++ b/bin/varnishd/cache/cache_cli.c @@ -111,7 +111,7 @@ CLI_Run(void) /*--------------------------------------------------------------------*/ static struct cli_proto cli_cmds[] = { - { CLICMD_PING, "i", VCLS_func_ping }, + { CLICMD_PING, "i", VCLS_func_ping, VCLS_func_ping_json }, { CLICMD_HELP, "i", VCLS_func_help, VCLS_func_help_json }, { NULL } }; diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c index 3304ef03c..3677eb620 100644 --- a/bin/varnishd/mgt/mgt_cli.c +++ b/bin/varnishd/mgt/mgt_cli.c @@ -327,7 +327,7 @@ mcf_help_json(struct cli *cli, const char * const *av, void *priv) static struct cli_proto cli_auth[] = { { CLICMD_HELP, "", mcf_help, mcf_help_json }, - { CLICMD_PING, "", VCLS_func_ping }, + { CLICMD_PING, "", VCLS_func_ping, VCLS_func_ping_json }, { CLICMD_AUTH, "", mcf_auth }, { CLICMD_QUIT, "", VCLS_func_close }, { NULL } diff --git a/bin/varnishtest/tests/b00008.vtc b/bin/varnishtest/tests/b00008.vtc index 1ec361155..071e8c358 100644 --- a/bin/varnishtest/tests/b00008.vtc +++ b/bin/varnishtest/tests/b00008.vtc @@ -1,4 +1,4 @@ -varnishtest "Test CLI help and parameter functions" +varnishtest "Test CLI commands and parameter functions" varnish v1 -arg "-b ${bad_ip}:9080" @@ -28,6 +28,12 @@ varnish v1 -cliok "help" varnish v1 -clijson "help -j" +varnish v1 -cliok "backend.list" + +varnish v1 -cliok "ping" + +varnish v1 -clijson "ping -j" + varnish v1 -clierr 106 "param.set waiter HASH(0x8839c4c)" varnish v1 -cliok "param.set cli_limit 128" diff --git a/include/vcli_serve.h b/include/vcli_serve.h index 8378993c4..00b364ff4 100644 --- a/include/vcli_serve.h +++ b/include/vcli_serve.h @@ -105,3 +105,4 @@ cli_func_t VCLS_func_close; cli_func_t VCLS_func_help; cli_func_t VCLS_func_help_json; cli_func_t VCLS_func_ping; +cli_func_t VCLS_func_ping_json; diff --git a/lib/libvarnish/vcli_serve.c b/lib/libvarnish/vcli_serve.c index de7ebdbd8..fc8578c50 100644 --- a/lib/libvarnish/vcli_serve.c +++ b/lib/libvarnish/vcli_serve.c @@ -103,6 +103,16 @@ VCLS_func_ping(struct cli *cli, const char * const *av, void *priv) VCLI_Out(cli, "PONG %jd 1.0", (intmax_t)t); } +void v_matchproto_(cli_func_t) +VCLS_func_ping_json(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + VCLI_JSON_begin(cli, 2, av); + VCLI_Out(cli, ", \"PONG\"\n"); + VCLI_JSON_end(cli); +} + /*--------------------------------------------------------------------*/ void v_matchproto_(cli_func_t) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 404003e91 Fix a case I overlooked in the recent change to remove the NUL termination of the rxbuf. Message-ID: <20180816085312.C8B729BF86@lists.varnish-cache.org> commit 404003e91de67395f08c727df99fe479d0a73b11 Author: Poul-Henning Kamp Date: Thu Jun 14 07:47:58 2018 +0000 Fix a case I overlooked in the recent change to remove the NUL termination of the rxbuf. Found by: fgs diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index d1ad4d28e..ac1a2a86e 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -73,7 +73,7 @@ HTTP1_Complete(struct http_conn *htc) assert(htc->rxbuf_e <= htc->ws->r); /* Skip any leading white space */ - for (p = htc->rxbuf_b ; vct_islws(*p); p++) + for (p = htc->rxbuf_b ; p < htc->rxbuf_e && vct_islws(*p); p++) continue; if (p == htc->rxbuf_e) return (HTC_S_EMPTY); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:12 +0000 (UTC) Subject: [6.0] 878bb1d34 The backend probes can only access the backend under lock, because the backend might be going away, and since we cannot afford to hold the lock over VTP_Open(), we have to pull the VBE_vsc knowledge one level back up. Message-ID: <20180816085312.EB3E79BFA6@lists.varnish-cache.org> commit 878bb1d349df2fb57f8c8a5e6d0c010de417c6a4 Author: Poul-Henning Kamp Date: Thu Jun 14 08:37:05 2018 +0000 The backend probes can only access the backend under lock, because the backend might be going away, and since we cannot afford to hold the lock over VTP_Open(), we have to pull the VBE_vsc knowledge one level back up. Overlooked by: slink, phk Spotted by: Coverity Conflicts: bin/varnishd/cache/cache_backend.c bin/varnishd/cache/cache_backend.h diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index a727f5ec8..7408f05a4 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -59,6 +59,41 @@ static struct lock backends_mtx; /*--------------------------------------------------------------------*/ +void +VBE_Connect_Error(struct VSC_vbe *vsc, int err) +{ + + switch(err) { + case 0: + /* + * This is kind of brittle, but zero is the only + * value of errno we can trust to have no meaning. + */ + vsc->helddown++; + break; + case EACCES: + case EPERM: + vsc->fail_eacces++; + break; + case EADDRNOTAVAIL: + vsc->fail_eaddrnotavail++; + break; + case ECONNREFUSED: + vsc->fail_econnrefused++; + break; + case ENETUNREACH: + vsc->fail_enetunreach++; + break; + case ETIMEDOUT: + vsc->fail_etimedout++; + break; + default: + vsc->fail_other++; + } +} + +/*--------------------------------------------------------------------*/ + #define FIND_TMO(tmx, dst, bo, be) \ do { \ CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); \ @@ -78,7 +113,7 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo, unsigned force_fresh) { struct pfd *pfd; - int *fdp; + int *fdp, err; double tmod; char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE]; char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE]; @@ -114,12 +149,12 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo, bo->htc->doclose = SC_NULL; FIND_TMO(connect_timeout, tmod, bo, bp); - pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh, bp->vsc); + pfd = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh, &err); if (pfd == NULL) { + VBE_Connect_Error(bp->vsc, err); VSLb(bo->vsl, SLT_FetchError, "backend %s: fail errno %d (%s)", bp->director->display_name, errno, strerror(errno)); - // XXX: Per backend stats ? VSC_C_main->backend_fail++; bo->htc = NULL; return (NULL); diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h index b0a0442bd..9d88cd2b6 100644 --- a/bin/varnishd/cache/cache_backend.h +++ b/bin/varnishd/cache/cache_backend.h @@ -82,3 +82,4 @@ void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p, void VBP_Remove(struct backend *b); void VBP_Control(const struct backend *b, int stop); void VBP_Status(struct cli *cli, const struct backend *, int details); +void VBE_Connect_Error(struct VSC_vbe *, int err); diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 4945b8efd..ba1940838 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -275,7 +275,7 @@ vbp_write_proxy_v1(struct vbp_target *vt, int *sock) static void vbp_poke(struct vbp_target *vt) { - int s, tmo, i, proxy_header; + int s, tmo, i, proxy_header, err; double t_start, t_now, t_end; unsigned rlen, resp; char buf[8192], *p; @@ -285,11 +285,13 @@ vbp_poke(struct vbp_target *vt) t_start = t_now = VTIM_real(); t_end = t_start + vt->timeout; - s = VTP_Open(vt->tcp_pool, t_end - t_now, (const void **)&sa, - vt->backend->vsc); + s = VTP_Open(vt->tcp_pool, t_end - t_now, (const void **)&sa, &err); if (s < 0) { - bprintf(vt->resp_buf, "Open error %d (%s)", - errno, strerror(errno)); + bprintf(vt->resp_buf, "Open error %d (%s)", err, strerror(err)); + Lck_Lock(&vbp_mtx); + if (vt->backend) + VBE_Connect_Error(vt->backend->vsc, err); + Lck_Unlock(&vbp_mtx); return; } diff --git a/bin/varnishd/cache/cache_tcp_pool.c b/bin/varnishd/cache/cache_tcp_pool.c index d79273586..f33668b2f 100644 --- a/bin/varnishd/cache/cache_tcp_pool.c +++ b/bin/varnishd/cache/cache_tcp_pool.c @@ -45,8 +45,6 @@ #include "cache_tcp_pool.h" #include "cache_pool.h" -#include "VSC_vbe.h" - struct conn_pool; /*-------------------------------------------------------------------- @@ -379,13 +377,13 @@ VCP_Recycle(const struct worker *wrk, struct pfd **pfdp) */ static int -VCP_Open(struct conn_pool *cp, double tmo, const void **privp, - struct VSC_vbe *vsc) +VCP_Open(struct conn_pool *cp, double tmo, const void **privp, int *err) { int r; double h; CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); + AN(err); while (cp->holddown > 0) { Lck_Lock(&cp->mtx); @@ -400,8 +398,7 @@ VCP_Open(struct conn_pool *cp, double tmo, const void **privp, break; } - if (vsc) - vsc->helddown++; + *err = 0; errno = cp->holddown_errno; Lck_Unlock(&cp->mtx); return (-1); @@ -409,7 +406,9 @@ VCP_Open(struct conn_pool *cp, double tmo, const void **privp, r = cp->methods->open(cp, tmo, privp); - if (r >= 0 || vsc == NULL) + *err = errno; + + if (r >= 0) return (r); h = 0; @@ -418,28 +417,20 @@ VCP_Open(struct conn_pool *cp, double tmo, const void **privp, switch (errno) { case EACCES: case EPERM: - vsc->fail_eacces++; h = cache_param->backend_local_error_holddown; break; case EADDRNOTAVAIL: - vsc->fail_eaddrnotavail++; h = cache_param->backend_local_error_holddown; break; case ECONNREFUSED: - vsc->fail_econnrefused++; h = cache_param->backend_remote_error_holddown; break; case ENETUNREACH: - vsc->fail_enetunreach++; h = cache_param->backend_remote_error_holddown; break; - case ETIMEDOUT: - vsc->fail_etimedout++; - break; default: - vsc->fail_other++; + break; } - vsc->fail++; if (h == 0) return (r); @@ -498,13 +489,15 @@ VCP_Close(struct pfd **pfdp) static struct pfd * VCP_Get(struct conn_pool *cp, double tmo, struct worker *wrk, - unsigned force_fresh, struct VSC_vbe *vsc) + unsigned force_fresh, int *err) { struct pfd *pfd; CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + AN(err); + *err = 0; Lck_Lock(&cp->mtx); pfd = VTAILQ_FIRST(&cp->connlist); CHECK_OBJ_ORNULL(pfd, PFD_MAGIC); @@ -531,7 +524,7 @@ VCP_Get(struct conn_pool *cp, double tmo, struct worker *wrk, INIT_OBJ(pfd->waited, WAITED_MAGIC); pfd->state = PFD_STATE_USED; pfd->conn_pool = cp; - pfd->fd = VCP_Open(cp, tmo, &pfd->priv, vsc); + pfd->fd = VCP_Open(cp, tmo, &pfd->priv, err); if (pfd->fd < 0) { FREE_OBJ(pfd); Lck_Lock(&cp->mtx); @@ -809,10 +802,9 @@ VTP_Rel(struct tcp_pool **tpp) */ int -VTP_Open(struct tcp_pool *tp, double tmo, const void **privp, - struct VSC_vbe *vsc) +VTP_Open(struct tcp_pool *tp, double tmo, const void **privp, int *err) { - return (VCP_Open(tp->cp, tmo, privp, vsc)); + return (VCP_Open(tp->cp, tmo, privp, err)); } /*-------------------------------------------------------------------- @@ -843,10 +835,10 @@ VTP_Close(struct pfd **pfdp) struct pfd * VTP_Get(struct tcp_pool *tp, double tmo, struct worker *wrk, - unsigned force_fresh, struct VSC_vbe *vsc) + unsigned force_fresh, int *err) { - return VCP_Get(tp->cp, tmo, wrk, force_fresh, vsc); + return VCP_Get(tp->cp, tmo, wrk, force_fresh, err); } /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_tcp_pool.h b/bin/varnishd/cache/cache_tcp_pool.h index 9f640da73..7c25afda2 100644 --- a/bin/varnishd/cache/cache_tcp_pool.h +++ b/bin/varnishd/cache/cache_tcp_pool.h @@ -72,11 +72,10 @@ void VTP_Rel(struct tcp_pool **); * the pool is destroyed and all cached connections closed. */ -int VTP_Open(struct tcp_pool *, double tmo, const void **, - struct VSC_vbe *); +int VTP_Open(struct tcp_pool *, double tmo, const void **, int*); /* * Open a new connection and return the adress used. - * Errors will be accounted in the optional vsc + * errno will be returned in the last argument. */ void VTP_Close(struct pfd **); @@ -90,10 +89,10 @@ void VTP_Recycle(const struct worker *, struct pfd **); */ struct pfd *VTP_Get(struct tcp_pool *, double tmo, struct worker *, - unsigned force_fresh, struct VSC_vbe *); + unsigned force_fresh, int *err); /* * Get a (possibly) recycled connection. - * Open errors will be accounted in the optional vsc + * errno will be stored in err */ int VTP_Wait(struct worker *, struct pfd *, double tmo); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:13 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:13 +0000 (UTC) Subject: [6.0] 10ced1f29 Check the backend connection failures get counted Message-ID: <20180816085313.1DB0F9BFB5@lists.varnish-cache.org> commit 10ced1f29c3c71cec951b757d4d87bf01a5289a8 Author: Poul-Henning Kamp Date: Thu Jun 14 13:53:15 2018 +0000 Check the backend connection failures get counted diff --git a/bin/varnishtest/tests/b00015.vtc b/bin/varnishtest/tests/b00015.vtc index cc6df6d22..5f3b69c03 100644 --- a/bin/varnishtest/tests/b00015.vtc +++ b/bin/varnishtest/tests/b00015.vtc @@ -92,3 +92,6 @@ client c1 { } -run delay .1 + +varnish v1 -expect VBE.vcl1.foo.fail_econnrefused > 0 +varnish v1 -expect VBE.vcl1.foo.helddown > 0 From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:13 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:13 +0000 (UTC) Subject: [6.0] c403c025f Fix an h/2 thread leak Message-ID: <20180816085313.4077D9BFC4@lists.varnish-cache.org> commit c403c025f5573498952cf684179cc8ccdc7fce95 Author: Dag Haavi Finstad Date: Fri Jun 15 16:03:22 2018 +0200 Fix an h/2 thread leak If we failed to schedule a thread for a stream and it's not cleaned up prior to handling a request body, the rxthread would sit around waiting in h2_rx_data indefinitely. diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index c43a65f96..729f0a4ee 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -723,7 +723,7 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) (void)wrk; ASSERT_RXTHR(h2); - if (r2 == NULL) + if (r2 == NULL || !r2->scheduled) return (0); Lck_Lock(&h2->sess->mtx); AZ(h2->mailcall); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:13 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:13 +0000 (UTC) Subject: [6.0] 2438f21b4 h2: Avoid sending duplicate rst_stream frames on Pool_Task failure Message-ID: <20180816085313.655BC9BFD7@lists.varnish-cache.org> commit 2438f21b4833c69fc35e13d32180a37a6b0fc688 Author: Dag Haavi Finstad Date: Fri Jun 15 16:07:37 2018 +0200 h2: Avoid sending duplicate rst_stream frames on Pool_Task failure diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 729f0a4ee..7001b60fc 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -603,6 +603,7 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, r2->scheduled = 1; if (Pool_Task(wrk->pool, &req->task, TASK_QUEUE_STR) != 0) { r2->scheduled = 0; + r2->state = H2_S_CLOSED; return (H2SE_REFUSED_STREAM); //rfc7540,l,3326,3329 } return (0); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:13 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:13 +0000 (UTC) Subject: [6.0] 2486eadae Stabilize r02679 Message-ID: <20180816085313.B40A39BFF3@lists.varnish-cache.org> commit 2486eadae9f8aa5901c90d4eb17134aa65e1f5b8 Author: Dag Haavi Finstad Date: Fri Jun 15 16:12:54 2018 +0200 Stabilize r02679 Tune down h2_rx_window_low_water to make sure we don't get a window_update racing against the response frames. Fixes: #2709 diff --git a/bin/varnishtest/tests/r02679.vtc b/bin/varnishtest/tests/r02679.vtc index ca99d75e8..c0029782a 100644 --- a/bin/varnishtest/tests/r02679.vtc +++ b/bin/varnishtest/tests/r02679.vtc @@ -15,6 +15,7 @@ varnish v1 -vcl+backend { } -start varnish v1 -cliok "param.set feature +http2" +varnish v1 -cliok "param.set h2_rx_window_low_water 65535" client c1 { stream 1 { @@ -22,9 +23,7 @@ client c1 { txdata -datalen 1550 -nostrend rxwinup txdata -datalen 16000 -nostrend - rxwinup txdata -datalen 13919 - rxwinup rxresp expect resp.status == 200 } -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:13 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:13 +0000 (UTC) Subject: [6.0] c3c75f4fc Revert 88b2eb8e for now Message-ID: <20180816085313.EA0539C003@lists.varnish-cache.org> commit c3c75f4fc5ea3ee7d4f0e7ceb5225d2cb32ae089 Author: Federico G. Schwindt Date: Mon Jun 18 11:04:20 2018 +0100 Revert 88b2eb8e for now Should address #2666 and #2711. diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index d814944a2..e64bcfa41 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -244,10 +244,6 @@ tst_cb(const struct vev *ve, int what) VEV_Stop(vb, jp->evt); free(jp->evt); } - if (!jp->tst->ntodo) { - free(jp->tst->script); - FREE_OBJ(jp->tst); - } FREE_OBJ(jp); return (1); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:14 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:14 +0000 (UTC) Subject: [6.0] 6d845b8ad Also revert this as part of 44d28931 Message-ID: <20180816085314.2AA579C010@lists.varnish-cache.org> commit 6d845b8ad1ba3e5e6bb5230584490a0dc08e56c8 Author: Federico G. Schwindt Date: Wed Jun 20 13:23:40 2018 +0100 Also revert this as part of 44d28931 Should help with the ASAN builds in travis. diff --git a/tools/lsan.suppr b/tools/lsan.suppr index d08ee697c..b6d916a30 100644 --- a/tools/lsan.suppr +++ b/tools/lsan.suppr @@ -1,6 +1,5 @@ # varnishtest -leak:parse_string -leak:receive_frame +leak:varnishtest # pp->{def,min,max} leak:MCF_ParamConf # pp->{def,min,max} From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:14 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:14 +0000 (UTC) Subject: [6.0] 5fddc6936 Don't transition to CLOS_REM state until we've seen END_STREAM Message-ID: <20180816085314.5E5839C02E@lists.varnish-cache.org> commit 5fddc69365fb089e629199ab2bf854233e57c659 Author: Dag Haavi Finstad Date: Fri Jun 22 11:20:12 2018 +0200 Don't transition to CLOS_REM state until we've seen END_STREAM Previously we've been incorrectly transtitioning to CLOS_REM on END_HEADERS, which prevents us from seeing if a client incorrectly transmitted a DATA frame on a closed stream. This slightly complicates things in that we can now be in state OPEN with an inactive hpack decoding state, and we need to make sure on cleanup if that has already been finalized. This would be simpler if the h/2 spec had split the OPEN state in two parts, with an extra state transition on END_HEADERS. Again big thanks to @xcir for his help in diagnosing this. Fixes: #2623 diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 7001b60fc..2a0d73b81 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -225,7 +225,7 @@ h2_kill_req(struct worker *wrk, const struct h2_sess *h2, AZ(pthread_cond_signal(r2->cond)); r2 = NULL; } else { - if (r2->state == H2_S_OPEN) { + if (r2->state == H2_S_OPEN && r2->decode != NULL) { (void)h2h_decode_fini(h2, r2->decode); FREE_OBJ(r2->decode); } @@ -559,7 +559,8 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, assert(r2->state == H2_S_OPEN); h2e = h2h_decode_fini(h2, r2->decode); FREE_OBJ(r2->decode); - r2->state = H2_S_CLOS_REM; + if (h2->rxf_flags & H2FF_HEADERS_END_STREAM) + r2->state = H2_S_CLOS_REM; h2->new_req = NULL; if (h2e != NULL) { Lck_Lock(&h2->sess->mtx); @@ -693,7 +694,7 @@ h2_rx_continuation(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) h2_error h2e; ASSERT_RXTHR(h2); - if (r2 == NULL || r2->state != H2_S_OPEN) + if (r2 == NULL || r2->state != H2_S_OPEN || r2->req != h2->new_req) return (H2CE_PROTOCOL_ERROR); // XXX spec ? req = r2->req; h2e = h2h_decode_bytes(h2, r2->decode, h2->rxf_data, h2->rxf_len); @@ -726,6 +727,10 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) ASSERT_RXTHR(h2); if (r2 == NULL || !r2->scheduled) return (0); + if (r2->state >= H2_S_CLOS_REM) { + r2->error = H2SE_STREAM_CLOSED; + return (H2SE_STREAM_CLOSED); // rfc7540,l,1766,1769 + } Lck_Lock(&h2->sess->mtx); AZ(h2->mailcall); h2->mailcall = r2; @@ -780,6 +785,7 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) *lp = 0; Lck_Lock(&h2->sess->mtx); + assert (r2->state == H2_S_OPEN); r2->cond = &vc->wrk->cond; while (h2->mailcall != r2 && h2->error == 0 && r2->error == 0) AZ(Lck_CondWait(r2->cond, &h2->sess->mtx, 0)); @@ -803,8 +809,10 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) return (VFP_OK); } if (h2->rxf_len == 0) { - if (h2->rxf_flags & H2FF_DATA_END_STREAM) + if (h2->rxf_flags & H2FF_DATA_END_STREAM) { retval = VFP_END; + r2->state = H2_S_CLOS_REM; + } } h2->mailcall = NULL; AZ(pthread_cond_signal(h2->cond)); diff --git a/bin/varnishtest/tests/t02014.vtc b/bin/varnishtest/tests/t02014.vtc index bc49f4e84..17489d362 100644 --- a/bin/varnishtest/tests/t02014.vtc +++ b/bin/varnishtest/tests/t02014.vtc @@ -1,8 +1,8 @@ varnishtest "Exercise h/2 sender flow control code" -barrier b1 sock 3 +barrier b1 sock 3 -cyclic -server s1 { +server s1 -repeat 2 { rxreq txresp -bodylen 66300 } -start @@ -45,3 +45,59 @@ client c1 { stream 0 -wait } -run + +client c1 { + stream 0 { + barrier b1 sync + } -start + + stream 1 { + txreq + txdata -data "fail" + rxrst + expect rst.err == STREAM_CLOSED + barrier b1 sync + } -run + + stream 0 -wait +} -run + +client c1 { + stream 0 { + barrier b1 sync + barrier b1 sync + delay .5 + txwinup -size 256 + delay .5 + txwinup -size 256 + delay .5 + txwinup -size 256 + + } -start + + stream 1 { + txreq -req "POST" -nostrend + txdata -data "ok" + rxwinup + txdata -data "fail" + rxrst + expect rst.err == STREAM_CLOSED + barrier b1 sync + } -run + + stream 3 { + txreq + barrier b1 sync + delay .5 + txwinup -size 256 + delay .5 + txwinup -size 256 + delay .5 + txwinup -size 256 + rxresp + expect resp.status == 200 + expect resp.bodylen == 66300 + } -run + + stream 0 -wait +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:14 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:14 +0000 (UTC) Subject: [6.0] baf7a2d0f Proper END_STREAM handling Message-ID: <20180816085314.D73B99C047@lists.varnish-cache.org> commit baf7a2d0f8dcae5647425a748f39bf84af02fba4 Author: Dag Haavi Finstad Date: Fri Jun 22 15:32:10 2018 +0200 Proper END_STREAM handling The previous commit made the assumption that END_STREAM is in the last of the frames in a header block. This is not necessarily the case. diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 2a0d73b81..9dede792e 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -559,9 +559,12 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, assert(r2->state == H2_S_OPEN); h2e = h2h_decode_fini(h2, r2->decode); FREE_OBJ(r2->decode); - if (h2->rxf_flags & H2FF_HEADERS_END_STREAM) - r2->state = H2_S_CLOS_REM; h2->new_req = NULL; + if (r2->req->req_body_status == REQ_BODY_NONE) { + /* REQ_BODY_NONE implies one of the frames in the + * header block contained END_STREAM */ + r2->state = H2_S_CLOS_REM; + } if (h2e != NULL) { Lck_Lock(&h2->sess->mtx); VSLb(h2->vsl, SLT_Debug, "HPACK/FINI %s", h2e->name); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:15 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:15 +0000 (UTC) Subject: [6.0] 745924a09 Apply workaround for macos Message-ID: <20180816085315.129829C062@lists.varnish-cache.org> commit 745924a09e0488732ae997fb8f505cb8b2fef257 Author: Federico G. Schwindt Date: Sat Jun 23 11:24:23 2018 +0100 Apply workaround for macos A bound socket will timeout instead of refusing the connection. Should fix b00015.vtc under macos. diff --git a/bin/varnishtest/vtc_main.c b/bin/varnishtest/vtc_main.c index e64bcfa41..e85ae92b7 100644 --- a/bin/varnishtest/vtc_main.c +++ b/bin/varnishtest/vtc_main.c @@ -492,6 +492,15 @@ ip_magic(void) VTCP_myname(fd, abuf, sizeof abuf, pbuf, sizeof(pbuf)); extmacro_def("localhost", "%s", abuf); +#if defined (__APPLE__) + /* + * In MacOS a bound socket that is not listening will timeout + * instead of refusing the connection so close it and hope + * for the best. + */ + VTCP_close(&fd); +#endif + /* Expose a backend that is forever down. */ extmacro_def("bad_backend", "%s %s", abuf, pbuf); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:15 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:15 +0000 (UTC) Subject: [6.0] 2dfd573fa Accurate ban statistics except for a few remaining corner cases Message-ID: <20180816085315.3E8039C07A@lists.varnish-cache.org> commit 2dfd573fae79ee4f8bd48ceed45dcc69720234dc Author: Nils Goroll Date: Wed Jun 20 13:39:09 2018 +0200 Accurate ban statistics except for a few remaining corner cases For ban statistics, we updated VSC_C_main directly, so if we raced Pool_Sumstat(), that could undo our changes. This patch fixes statistics by using the per-worker statistics cache except for the following remaining corner cases: * bans_persisted_* counters receive absolut updates, which does not seem to fit the incremental updates via the per-worker stats. I've kept these cases untouched and marked with comments. Worst that should happen here are temporary inconsistencies until the next absolute update. * For BAN_Reload(), my understanding is that it should only happen during init, so we continue to update VSC_C_main directly. * For bans via the cli, we would need to grab the wstat lock, which, at the moment, is private to the worker implementation. Until we make a change here, we could miss a ban increment from the cli. * for VCL bans from vcl_init / fini, we do not have access to the worker struct at the moment, so for now we also accept an inconsistency here. Fixes #2716 for relevant cases diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index f349d4f54..2298feaad 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -570,7 +570,7 @@ struct sess { struct ban_proto *BAN_Build(void); const char *BAN_AddTest(struct ban_proto *, const char *, const char *, const char *); -const char *BAN_Commit(struct ban_proto *b); +const char *BAN_Commit(struct ban_proto *b, struct VSC_main *stats); void BAN_Abandon(struct ban_proto *b); /* cache_cli.c [CLI] */ diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c index 0393deea6..b3203a042 100644 --- a/bin/varnishd/cache/cache_ban.c +++ b/bin/varnishd/cache/cache_ban.c @@ -152,7 +152,7 @@ ban_equal(const uint8_t *bs1, const uint8_t *bs2) } void -ban_mark_completed(struct ban *b) +ban_mark_completed(struct ban *b, struct VSC_main *stats) { unsigned ln; @@ -166,8 +166,12 @@ ban_mark_completed(struct ban *b) b->spec[BANS_FLAGS] |= BANS_FLAG_COMPLETED; VWMB(); vbe32enc(b->spec + BANS_LENGTH, BANS_HEAD_LEN); - VSC_C_main->bans_completed++; + stats->bans_completed++; bans_persisted_fragmentation += ln - ban_len(b->spec); + /* + * XXX absolute update of gauges - may be inaccurate for + * Pool_Sumstat race + */ VSC_C_main->bans_persisted_fragmentation = bans_persisted_fragmentation; } @@ -315,6 +319,10 @@ ban_export(void) assert(VSB_len(vsb) == ln); STV_BanExport((const uint8_t *)VSB_data(vsb), VSB_len(vsb)); VSB_destroy(&vsb); + /* + * XXX absolute update of gauges - may be inaccurate for Pool_Sumstat + * race + */ VSC_C_main->bans_persisted_bytes = bans_persisted_bytes = ln; VSC_C_main->bans_persisted_fragmentation = @@ -359,7 +367,7 @@ ban_reload(const uint8_t *ban, unsigned len) struct ban *b, *b2; int duplicate = 0; double t0, t1, t2 = 9e99; - + struct VSC_main *stats = VSC_C_main; // XXX accurate? ASSERT_CLI(); Lck_AssertHeld(&ban_mtx); @@ -378,8 +386,8 @@ ban_reload(const uint8_t *ban, unsigned len) duplicate = 1; } - VSC_C_main->bans++; - VSC_C_main->bans_added++; + stats->bans++; + stats->bans_added++; b2 = ban_alloc(); AN(b2); @@ -387,18 +395,22 @@ ban_reload(const uint8_t *ban, unsigned len) AN(b2->spec); memcpy(b2->spec, ban, len); if (ban[BANS_FLAGS] & BANS_FLAG_REQ) { - VSC_C_main->bans_req++; + stats->bans_req++; b2->flags |= BANS_FLAG_REQ; } if (duplicate) - VSC_C_main->bans_dups++; + stats->bans_dups++; if (duplicate || (ban[BANS_FLAGS] & BANS_FLAG_COMPLETED)) - ban_mark_completed(b2); + ban_mark_completed(b2, stats); if (b == NULL) VTAILQ_INSERT_TAIL(&ban_head, b2, list); else VTAILQ_INSERT_BEFORE(b, b2, list); bans_persisted_bytes += len; + /* + * XXX absolute update of gauges - may be inaccurate for Pool_Sumstat + * race + */ VSC_C_main->bans_persisted_bytes = bans_persisted_bytes; /* Hunt down older duplicates */ @@ -406,8 +418,8 @@ ban_reload(const uint8_t *ban, unsigned len) if (b->flags & BANS_FLAG_COMPLETED) continue; if (ban_equal(b->spec, ban)) { - ban_mark_completed(b); - VSC_C_main->bans_dups++; + ban_mark_completed(b, stats); + stats->bans_dups++; } } } @@ -536,13 +548,16 @@ BAN_CheckObject(struct worker *wrk, struct objcore *oc, struct req *req) struct vsl_log *vsl; struct ban *b0, *bn; unsigned tests; + struct VSC_main *stats; + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); Lck_AssertHeld(&oc->objhead->mtx); assert(oc->refcnt > 0); vsl = req->vsl; + stats = wrk->stats; CHECK_OBJ_NOTNULL(oc->ban, BAN_MAGIC); @@ -585,8 +600,8 @@ BAN_CheckObject(struct worker *wrk, struct objcore *oc, struct req *req) Lck_Lock(&ban_mtx); bn->refcount--; - VSC_C_main->bans_tested++; - VSC_C_main->bans_tests_tested += tests; + stats->bans_tested++; + stats->bans_tests_tested += tests; if (b == bn) { /* not banned */ @@ -609,7 +624,7 @@ BAN_CheckObject(struct worker *wrk, struct objcore *oc, struct req *req) return (0); } else { VSLb(vsl, SLT_ExpBan, "%u banned lookup", ObjGetXID(wrk, oc)); - VSC_C_main->bans_obj_killed++; + stats->bans_obj_killed++; return (1); } } @@ -655,8 +670,10 @@ ccf_ban(struct cli *cli, const char * const *av, void *priv) break; } - if (err == NULL) - err = BAN_Commit(bp); + if (err == NULL) { + // XXX racy - grab wstat lock? + err = BAN_Commit(bp, VSC_C_main); + } if (err != NULL) { VCLI_Out(cli, "%s", err); @@ -804,9 +821,9 @@ BAN_Init(void) bp = BAN_Build(); AN(bp); AZ(pthread_cond_init(&ban_lurker_cond, NULL)); - AZ(BAN_Commit(bp)); + AZ(BAN_Commit(bp, VSC_C_main)); Lck_Lock(&ban_mtx); - ban_mark_completed(VTAILQ_FIRST(&ban_head)); + ban_mark_completed(VTAILQ_FIRST(&ban_head), VSC_C_main); Lck_Unlock(&ban_mtx); } diff --git a/bin/varnishd/cache/cache_ban.h b/bin/varnishd/cache/cache_ban.h index 6267c4eed..d534f6e99 100644 --- a/bin/varnishd/cache/cache_ban.h +++ b/bin/varnishd/cache/cache_ban.h @@ -109,7 +109,7 @@ extern pthread_cond_t ban_lurker_cond; extern uint64_t bans_persisted_bytes; extern uint64_t bans_persisted_fragmentation; -void ban_mark_completed(struct ban *b); +void ban_mark_completed(struct ban *b, struct VSC_main *stats); unsigned ban_len(const uint8_t *banspec); void ban_info_new(const uint8_t *ban, unsigned len); void ban_info_drop(const uint8_t *ban, unsigned len); diff --git a/bin/varnishd/cache/cache_ban_build.c b/bin/varnishd/cache/cache_ban_build.c index 717f5c506..95f82bcc8 100644 --- a/bin/varnishd/cache/cache_ban_build.c +++ b/bin/varnishd/cache/cache_ban_build.c @@ -246,7 +246,7 @@ BAN_AddTest(struct ban_proto *bp, */ const char * -BAN_Commit(struct ban_proto *bp) +BAN_Commit(struct ban_proto *bp, struct VSC_main *stats) { struct ban *b, *bi; ssize_t ln; @@ -294,15 +294,19 @@ BAN_Commit(struct ban_proto *bp) VTAILQ_INSERT_HEAD(&ban_head, b, list); ban_start = b; - VSC_C_main->bans++; - VSC_C_main->bans_added++; + stats->bans++; + stats->bans_added++; bans_persisted_bytes += ln; + /* + * XXX absolute update of gauges - may be inaccurate for Pool_Sumstat + * race + */ VSC_C_main->bans_persisted_bytes = bans_persisted_bytes; if (b->flags & BANS_FLAG_OBJ) - VSC_C_main->bans_obj++; + stats->bans_obj++; if (b->flags & BANS_FLAG_REQ) - VSC_C_main->bans_req++; + stats->bans_req++; if (bi != NULL) ban_info_new(b->spec, ln); /* Notify stevedores */ @@ -313,8 +317,8 @@ BAN_Commit(struct ban_proto *bp) bi = VTAILQ_NEXT(bi, list)) { if (!(bi->flags & BANS_FLAG_COMPLETED) && ban_equal(b->spec, bi->spec)) { - ban_mark_completed(bi); - VSC_C_main->bans_dups++; + ban_mark_completed(bi, stats); + stats->bans_dups++; } } } diff --git a/bin/varnishd/cache/cache_ban_lurker.c b/bin/varnishd/cache/cache_ban_lurker.c index f59b888ce..343009dd5 100644 --- a/bin/varnishd/cache/cache_ban_lurker.c +++ b/bin/varnishd/cache/cache_ban_lurker.c @@ -62,7 +62,7 @@ ban_kick_lurker(void) */ static int -ban_cleantail(const struct ban *victim) +ban_cleantail(const struct ban *victim, struct VSC_main *stats) { struct ban *b, *bt; struct banhead_s freelist = VTAILQ_HEAD_INITIALIZER(freelist); @@ -78,17 +78,21 @@ ban_cleantail(const struct ban *victim) if (b != VTAILQ_FIRST(&ban_head) && b->refcount == 0) { assert(VTAILQ_EMPTY(&b->objcore)); if (b->flags & BANS_FLAG_COMPLETED) - VSC_C_main->bans_completed--; + stats->bans_completed--; if (b->flags & BANS_FLAG_OBJ) - VSC_C_main->bans_obj--; + stats->bans_obj--; if (b->flags & BANS_FLAG_REQ) - VSC_C_main->bans_req--; - VSC_C_main->bans--; - VSC_C_main->bans_deleted++; + stats->bans_req--; + stats->bans--; + stats->bans_deleted++; VTAILQ_REMOVE(&ban_head, b, list); VTAILQ_INSERT_TAIL(&freelist, b, list); bans_persisted_fragmentation += ban_len(b->spec); + /* + * XXX absolute update of gauges - may be inaccurate for + * Pool_Sumstat race + */ VSC_C_main->bans_persisted_fragmentation = bans_persisted_fragmentation; ban_info_drop(b->spec, ban_len(b->spec)); @@ -121,7 +125,7 @@ ban_cleantail(const struct ban *victim) */ static struct objcore * -ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt) +ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt, struct VSC_main *stats) { struct objhead *oh; struct objcore *oc, *noc; @@ -151,7 +155,7 @@ ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt) /* hold off to give lookup a chance and reiterate */ Lck_Unlock(&ban_mtx); - VSC_C_main->bans_lurker_contention++; + stats->bans_lurker_contention++; VSL_Flush(vsl, 0); VTIM_sleep(cache_param->ban_lurker_holdoff); Lck_Lock(&ban_mtx); @@ -205,6 +209,10 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt, struct objcore *oc; unsigned tests; int i; + struct VSC_main *stats; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + stats = wrk->stats; /* * First see if there is anything to do, and if so, insert markers @@ -224,7 +232,7 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt, VTIM_sleep(cache_param->ban_lurker_sleep); ban_batch = 0; } - oc = ban_lurker_getfirst(vsl, bt); + oc = ban_lurker_getfirst(vsl, bt, stats); if (oc == NULL) return; i = 0; @@ -248,21 +256,21 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt, tests = 0; i = ban_evaluate(wrk, bl->spec, oc, NULL, &tests); - VSC_C_main->bans_lurker_tested++; - VSC_C_main->bans_lurker_tests_tested += tests; + stats->bans_lurker_tested++; + stats->bans_lurker_tests_tested += tests; } if (i) { if (kill) { VSLb(vsl, SLT_ExpBan, "%u killed for lurker cutoff", ObjGetXID(wrk, oc)); - VSC_C_main-> + stats-> bans_lurker_obj_killed_cutoff++; } else { VSLb(vsl, SLT_ExpBan, "%u banned by lurker", ObjGetXID(wrk, oc)); - VSC_C_main->bans_lurker_obj_killed++; + stats->bans_lurker_obj_killed++; } HSH_Kill(oc); break; @@ -303,10 +311,14 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl) struct banhead_s obans; double d, dt, n; unsigned count = 0, cutoff = UINT_MAX; + struct VSC_main *stats; + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + stats = wrk->stats; dt = 49.62; // Random, non-magic if (cache_param->ban_lurker_sleep == 0) { - (void)ban_cleantail(NULL); + (void)ban_cleantail(NULL, stats); return (dt); } if (cache_param->ban_cutoff > 0) @@ -346,7 +358,7 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl) * containted the first oban, all obans were on the tail and we're * done. */ - if (ban_cleantail(VTAILQ_FIRST(&obans))) + if (ban_cleantail(VTAILQ_FIRST(&obans), stats)) return (dt); if (VTAILQ_FIRST(&obans) == NULL) @@ -374,7 +386,7 @@ ban_lurker_work(struct worker *wrk, struct vsl_log *vsl) Lck_Lock(&ban_mtx); VTAILQ_FOREACH(b, &obans, l_list) { - ban_mark_completed(b); + ban_mark_completed(b, stats); if (b == bd) break; } diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 8a31ee157..c4c709aa7 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -558,6 +558,26 @@ VRT_synth_page(VRT_CTX, const char *str, ...) /*--------------------------------------------------------------------*/ +static struct VSC_main * +vrt_stats(VRT_CTX) +{ + struct worker *wrk; + + if (ctx->req) { + CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); + wrk = ctx->req->wrk; + } else if (ctx->bo) { + CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); + wrk = ctx->bo->wrk; + } else { + // XXX + return (VSC_C_main); + } + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + return (wrk->stats); +} + VCL_VOID VRT_ban_string(VRT_CTX, VCL_STRING str) { @@ -613,7 +633,7 @@ VRT_ban_string(VRT_CTX, VCL_STRING str) break; } if (av[++i] == NULL) { - err = BAN_Commit(bp); + err = BAN_Commit(bp, vrt_stats(ctx)); if (err == NULL) bp = NULL; else diff --git a/include/vrt.h b/include/vrt.h index fdc454bba..936aa207f 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -123,6 +123,7 @@ struct vsc_seg; struct vsmw_cluster; struct vsl_log; struct ws; +struct VSC_main; struct strands { int n; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:15 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:15 +0000 (UTC) Subject: [6.0] 92ee4e482 Shard director: add documentation from 9b8f6e21809bf867eb5bd792331484d0e70eb367 Message-ID: <20180816085315.7F57E9C08D@lists.varnish-cache.org> commit 92ee4e482ae3dee421683ff126192f26d7647ec4 Author: Nils Goroll Date: Tue Jun 26 10:16:32 2018 +0200 Shard director: add documentation from 9b8f6e21809bf867eb5bd792331484d0e70eb367 diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index a50ff2f4b..797098abd 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -42,6 +42,44 @@ #include "shard_dir.h" #include "shard_cfg.h" +/* ------------------------------------------------------------------------- + * shard director: LAZY mode (vdi resolve function), parameter objects + * + * By associating a parameter object with a shard director, we enable LAZY + * lookups as with the other directors. Parameter objects are defined with VCL + * scope (normal vmod objects), but can be overridden per backend request using + * a task priv. + * + * We use the same concept to carry shard.backend() parameters to vdi resolve + * for LAZY mode: They get saved in a per-director task scope parameter object. + * + * Each object points to another object providing defaults for values which are + * not defined. + * + * Actual resolution of the various parameter objects does not happen before + * they are used, which enabled changing them independently (ie, shard + * .backend() parameters have precedence over an associated parameter object, + * which by itself can be overridden). + * + * Overview of parameter objects (pointers are alternatives) + * + * shard() director shard_param() object default praram + * + * ---------------------------------> vmod static + * VCL obj / -> + * .param -+---------> VCL obj / _ + * .default -------- /| + * / + * ^ / + * | / + * / + * .default / + * -------------> TASK priv / + * / / + * .default ----------------------------- + * TASK priv + */ + /* ------------------------------------------------------------------------- * method arguments and set parameters bitmask in vmod_directors_shard_param */ From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:15 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:15 +0000 (UTC) Subject: [6.0] aa809b5dd polish: use TAKE_OBJ_NOTNULL Message-ID: <20180816085315.B8D6B9C099@lists.varnish-cache.org> commit aa809b5dd2fb36b76604eaf0d6e71052fcb7738f Author: Nils Goroll Date: Tue Jun 26 10:39:21 2018 +0200 polish: use TAKE_OBJ_NOTNULL diff --git a/lib/libvmod_directors/shard_dir.c b/lib/libvmod_directors/shard_dir.c index 7a667c368..a83fc44dc 100644 --- a/lib/libvmod_directors/shard_dir.c +++ b/lib/libvmod_directors/shard_dir.c @@ -241,11 +241,7 @@ sharddir_delete(struct sharddir **sharddp) { struct sharddir *shardd; - AN(sharddp); - shardd = *sharddp; - *sharddp = NULL; - - CHECK_OBJ_NOTNULL(shardd, SHARDDIR_MAGIC); + TAKE_OBJ_NOTNULL(shardd, sharddp, SHARDDIR_MAGIC); shardcfg_delete(shardd); AZ(pthread_rwlock_destroy(&shardd->mtx)); FREE_OBJ(shardd); diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index 797098abd..98f9c0321 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -263,10 +263,9 @@ vmod_shard__init(VRT_CTX, struct vmod_directors_shard **vshardp, VCL_VOID v_matchproto_(td_directors_shard__fini) vmod_shard__fini(struct vmod_directors_shard **vshardp) { - struct vmod_directors_shard *vshard = *vshardp; + struct vmod_directors_shard *vshard; - *vshardp = NULL; - CHECK_OBJ_NOTNULL(vshard, VMOD_SHARD_SHARD_MAGIC); + TAKE_OBJ_NOTNULL(vshard, vshardp, VMOD_SHARD_SHARD_MAGIC); sharddir_delete(&vshard->shardd); free(vshard->dir->vcl_name); FREE_OBJ(vshard->dir); @@ -794,12 +793,11 @@ vmod_shard_param__init(VRT_CTX, VCL_VOID v_matchproto_(td_directors_shard_param__fini) vmod_shard_param__fini(struct vmod_directors_shard_param **pp) { - struct vmod_directors_shard_param *p = *pp; + struct vmod_directors_shard_param *p; - if (p == NULL) + if (*pp == NULL) return; - *pp = NULL; - CHECK_OBJ_NOTNULL(p, VMOD_SHARD_SHARD_PARAM_MAGIC); + TAKE_OBJ_NOTNULL(p, pp, VMOD_SHARD_SHARD_PARAM_MAGIC); FREE_OBJ(p); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:15 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:15 +0000 (UTC) Subject: [6.0] a6533c742 Use a separate condvar for connection-level flow control updates Message-ID: <20180816085315.EE9199C0B5@lists.varnish-cache.org> commit a6533c7427a328041221484dd357c94cb77f8d0e Author: Dag Haavi Finstad Date: Wed Jun 27 13:27:34 2018 +0200 Use a separate condvar for connection-level flow control updates The current flow control code's use of h2->cond is racy. h2->cond is already used for handing over a DATA frame to a stream thread. In the event that we have both streams waiting on this condvar for window updates and at the same time the rxthread gets signaled for a DATA frame, we could end up waking up the wrong thread and the rxthread gets stuck forever. This commit addresses this by using a separate condvar for window updates. An alternative would be to always issue a broadcast on h2->cond instead of signal, but I found this approach much cleaner. Probably fixes: #2623 diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h index a1d6f849b..fbc190535 100644 --- a/bin/varnishd/http2/cache_http2.h +++ b/bin/varnishd/http2/cache_http2.h @@ -145,6 +145,7 @@ struct h2_sess { pthread_t rxthr; struct h2_req *mailcall; pthread_cond_t *cond; + pthread_cond_t winupd_cond[1]; struct sess *sess; int refcnt; diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 9dede792e..e5106e8a4 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -369,7 +369,7 @@ h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) Lck_Lock(&h2->sess->mtx); r2->t_window += wu; if (r2 == h2->req0) - AZ(pthread_cond_broadcast(h2->cond)); + AZ(pthread_cond_broadcast(h2->winupd_cond)); else if (r2->cond != NULL) AZ(pthread_cond_signal(r2->cond)); Lck_Unlock(&h2->sess->mtx); diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index cfbb51be7..7c290bf9d 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -213,7 +213,7 @@ h2_do_window(struct worker *wrk, struct h2_req *r2, r2->cond = NULL; } while (h2->req0->t_window <= 0 && h2_errcheck(r2, h2) == 0) { - AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0)); + AZ(Lck_CondWait(h2->winupd_cond, &h2->sess->mtx, 0)); } if (h2_errcheck(r2, h2) == 0) { diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index b350f05c3..c0545265c 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -123,6 +123,7 @@ h2_init_sess(const struct worker *wrk, struct sess *sp, h2->htc->rfd = &sp->fd; h2->sess = sp; h2->rxthr = pthread_self(); + AZ(pthread_cond_init(h2->winupd_cond, NULL)); VTAILQ_INIT(&h2->streams); VTAILQ_INIT(&h2->txqueue); h2_local_settings(&h2->local_settings); @@ -150,6 +151,7 @@ h2_del_sess(struct worker *wrk, struct h2_sess *h2, enum sess_close reason) assert(VTAILQ_EMPTY(&h2->streams)); VHT_Fini(h2->dectbl); + AZ(pthread_cond_destroy(h2->winupd_cond)); req = h2->srq; AZ(req->ws->r); sp = h2->sess; @@ -404,7 +406,7 @@ h2_new_session(struct worker *wrk, void *arg) if (r2->cond != NULL) AZ(pthread_cond_signal(r2->cond)); } - AZ(pthread_cond_broadcast(h2->cond)); + AZ(pthread_cond_broadcast(h2->winupd_cond)); Lck_Unlock(&h2->sess->mtx); while (1) { again = 0; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:16 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:16 +0000 (UTC) Subject: [6.0] ca354bdde Ensure that only the rxthread gets to use h2->cond in h2_send_get Message-ID: <20180816085316.212529C0CD@lists.varnish-cache.org> commit ca354bdde61b90b6e41cfbc560d75e7b90a9567a Author: Dag Haavi Finstad Date: Wed Jun 27 13:36:04 2018 +0200 Ensure that only the rxthread gets to use h2->cond in h2_send_get Future-proofing to avoid mistakenly introducing another race down the line. diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index 7c290bf9d..054796e4b 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -45,6 +45,8 @@ h2_send_get(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); Lck_AssertHeld(&h2->sess->mtx); + if (&wrk->cond == h2->cond) + ASSERT_RXTHR(h2); r2->wrk = wrk; VTAILQ_INSERT_TAIL(&h2->txqueue, r2, tx_list); while (VTAILQ_FIRST(&h2->txqueue) != r2) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:16 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:16 +0000 (UTC) Subject: [6.0] b0e924cdf tell the truth about vmod filenames Message-ID: <20180816085316.4F7E89C0E0@lists.varnish-cache.org> commit b0e924cdf6505cbd5d1ffb8a95c2aef1a35f011e Author: Nils Goroll Date: Wed Jun 27 19:52:39 2018 +0200 tell the truth about vmod filenames diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c index 4e11ce5fe..ffd039ebc 100644 --- a/bin/varnishd/cache/cache_vrt_vmod.c +++ b/bin/varnishd/cache/cache_vrt_vmod.c @@ -93,7 +93,8 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm, dlhdl = dlopen(backup, RTLD_NOW | RTLD_LOCAL); if (dlhdl == NULL) { - VSB_printf(ctx->msg, "Loading vmod %s from %s:\n", nm, backup); + VSB_printf(ctx->msg, "Loading vmod %s from %s (%s):\n", + nm, backup, path); VSB_printf(ctx->msg, "dlopen() failed: %s\n", dlerror()); return (1); } @@ -113,8 +114,8 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm, if (d == NULL || d->file_id == NULL || strcmp(d->file_id, file_id)) { - VSB_printf(ctx->msg, - "Loading vmod %s from %s:\n", nm, path); + VSB_printf(ctx->msg, "Loading vmod %s from %s (%s):\n", + nm, backup, path); VSB_printf(ctx->msg, "This is no longer the same file seen by" " the VCL-compiler.\n"); @@ -129,8 +130,8 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm, d->func_len <= 0 || d->proto == NULL || d->json == NULL) { - VSB_printf(ctx->msg, - "Loading VMOD %s from %s:\n", nm, path); + VSB_printf(ctx->msg, "Loading vmod %s from %s (%s):\n", + nm, backup, path); VSB_printf(ctx->msg, "VMOD data is mangled.\n"); (void)dlclose(v->hdl); FREE_OBJ(v); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:16 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:16 +0000 (UTC) Subject: [6.0] 7a5494896 Get the probe's VTP reference in the probe code Message-ID: <20180816085316.755479C0E9@lists.varnish-cache.org> commit 7a54948963c1f486c0d377de0360de14e37f26dd Author: Nils Goroll Date: Thu Jun 28 14:27:28 2018 +0200 Get the probe's VTP reference in the probe code ... not in the caller diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 7408f05a4..6ad610f5d 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -525,10 +525,8 @@ VRT_new_backend_clustered(VRT_CTX, struct vsmw_cluster *vc, vrt->path, vbe_proto_ident); Lck_Unlock(&backends_mtx); - if (vbp != NULL) { - VTP_AddRef(be->tcp_pool); + if (vbp != NULL) VBP_Insert(be, vbp, be->tcp_pool); - } be->vsc = VSC_vbe_New(vc, &be->vsc_seg, "%s.%s", VCL_Name(ctx->vcl), vrt->vcl_name); diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index ba1940838..0ae04956c 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -651,6 +651,7 @@ VBP_Insert(struct backend *b, const struct vrt_backend_probe *vp, XXXAN(vt); vt->tcp_pool = tp; + VTP_AddRef(vt->tcp_pool); vt->backend = b; b->probe = vt; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:16 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:16 +0000 (UTC) Subject: [6.0] 346eb5d1c Simplify memory handling around struct h2h_decode Message-ID: <20180816085316.A84569C0FF@lists.varnish-cache.org> commit 346eb5d1cbcd830f5391a8d7ba3312b1ebcb890c Author: Dag Haavi Finstad Date: Fri Jun 29 15:04:11 2018 +0200 Simplify memory handling around struct h2h_decode Since we verify that header blocks are not interleaved, and we zero the struct h2h_decode on every new header block, there is no need to malloc a separate struct h2h_decode per stream. diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h index fbc190535..792fd985a 100644 --- a/bin/varnishd/http2/cache_http2.h +++ b/bin/varnishd/http2/cache_http2.h @@ -127,7 +127,6 @@ struct h2_req { VTAILQ_ENTRY(h2_req) list; int64_t t_window; int64_t r_window; - struct h2h_decode *decode; /* Where to wake this stream up */ struct worker *wrk; @@ -161,6 +160,7 @@ struct h2_sess { struct ws *ws; struct http_conn *htc; struct vsl_log *vsl; + struct h2h_decode *decode; struct vht_table dectbl[1]; unsigned rxf_len; @@ -208,10 +208,10 @@ struct h2h_decode { struct vhd_decode vhd[1]; }; -void h2h_decode_init(const struct h2_sess *h2, struct h2h_decode *d); -h2_error h2h_decode_fini(const struct h2_sess *h2, struct h2h_decode *d); -h2_error h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d, - const uint8_t *ptr, size_t len); +void h2h_decode_init(const struct h2_sess *h2); +h2_error h2h_decode_fini(const struct h2_sess *h2); +h2_error h2h_decode_bytes(struct h2_sess *h2, const uint8_t *ptr, + size_t len); /* cache_http2_send.c */ void H2_Send_Get(struct worker *, struct h2_sess *, struct h2_req *); diff --git a/bin/varnishd/http2/cache_http2_hpack.c b/bin/varnishd/http2/cache_http2_hpack.c index 3d7c2d00b..0524f3e32 100644 --- a/bin/varnishd/http2/cache_http2_hpack.c +++ b/bin/varnishd/http2/cache_http2_hpack.c @@ -164,13 +164,15 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) } void -h2h_decode_init(const struct h2_sess *h2, struct h2h_decode *d) +h2h_decode_init(const struct h2_sess *h2) { + struct h2h_decode *d; CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC); CHECK_OBJ_NOTNULL(h2->new_req, REQ_MAGIC); CHECK_OBJ_NOTNULL(h2->new_req->http, HTTP_MAGIC); - AN(d); + AN(h2->decode); + d = h2->decode; INIT_OBJ(d, H2H_DECODE_MAGIC); VHD_Init(d->vhd); d->out_l = WS_Reserve(h2->new_req->http->ws, 0); @@ -189,11 +191,13 @@ h2h_decode_init(const struct h2_sess *h2, struct h2h_decode *d) * is a stream level error. */ h2_error -h2h_decode_fini(const struct h2_sess *h2, struct h2h_decode *d) +h2h_decode_fini(const struct h2_sess *h2) { h2_error ret; + struct h2h_decode *d; CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC); + d = h2->decode; CHECK_OBJ_NOTNULL(h2->new_req, REQ_MAGIC); CHECK_OBJ_NOTNULL(d, H2H_DECODE_MAGIC); WS_ReleaseP(h2->new_req->http->ws, d->out); @@ -217,10 +221,10 @@ h2h_decode_fini(const struct h2_sess *h2, struct h2h_decode *d) * H2E_PROTOCOL_ERROR: Malformed header or duplicate pseudo-header. */ h2_error -h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d, - const uint8_t *in, size_t in_l) +h2h_decode_bytes(struct h2_sess *h2, const uint8_t *in, size_t in_l) { struct http *hp; + struct h2h_decode *d; size_t in_u = 0; CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC); @@ -229,6 +233,7 @@ h2h_decode_bytes(struct h2_sess *h2, struct h2h_decode *d, CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); CHECK_OBJ_NOTNULL(hp->ws, WS_MAGIC); AN(hp->ws->r); + d = h2->decode; CHECK_OBJ_NOTNULL(d, H2H_DECODE_MAGIC); /* Only H2E_ENHANCE_YOUR_CALM indicates that we should continue diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index e5106e8a4..f4cc294e5 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -225,10 +225,8 @@ h2_kill_req(struct worker *wrk, const struct h2_sess *h2, AZ(pthread_cond_signal(r2->cond)); r2 = NULL; } else { - if (r2->state == H2_S_OPEN && r2->decode != NULL) { - (void)h2h_decode_fini(h2, r2->decode); - FREE_OBJ(r2->decode); - } + if (r2->state == H2_S_OPEN && h2->new_req == r2->req) + (void)h2h_decode_fini(h2); } Lck_Unlock(&h2->sess->mtx); if (r2 != NULL) @@ -557,8 +555,7 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, ASSERT_RXTHR(h2); assert(r2->state == H2_S_OPEN); - h2e = h2h_decode_fini(h2, r2->decode); - FREE_OBJ(r2->decode); + h2e = h2h_decode_fini(h2); h2->new_req = NULL; if (r2->req->req_body_status == REQ_BODY_NONE) { /* REQ_BODY_NONE implies one of the frames in the @@ -650,9 +647,7 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); http_SetH(req->http, HTTP_HDR_PROTO, "HTTP/2.0"); - ALLOC_OBJ(r2->decode, H2H_DECODE_MAGIC); - AN(r2->decode); - h2h_decode_init(h2, r2->decode); + h2h_decode_init(h2); p = h2->rxf_data; l = h2->rxf_len; @@ -668,13 +663,12 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) l -= 5; p += 5; } - h2e = h2h_decode_bytes(h2, r2->decode, p, l); + h2e = h2h_decode_bytes(h2, p, l); if (h2e != NULL) { Lck_Lock(&h2->sess->mtx); VSLb(h2->vsl, SLT_Debug, "HPACK(hdr) %s", h2e->name); Lck_Unlock(&h2->sess->mtx); - (void)h2h_decode_fini(h2, r2->decode); - FREE_OBJ(r2->decode); + (void)h2h_decode_fini(h2); AZ(r2->req->ws->r); h2_del_req(wrk, r2); return (h2e); @@ -700,14 +694,13 @@ h2_rx_continuation(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) if (r2 == NULL || r2->state != H2_S_OPEN || r2->req != h2->new_req) return (H2CE_PROTOCOL_ERROR); // XXX spec ? req = r2->req; - h2e = h2h_decode_bytes(h2, r2->decode, h2->rxf_data, h2->rxf_len); + h2e = h2h_decode_bytes(h2, h2->rxf_data, h2->rxf_len); r2->req->acct.req_hdrbytes += h2->rxf_len; if (h2e != NULL) { Lck_Lock(&h2->sess->mtx); VSLb(h2->vsl, SLT_Debug, "HPACK(cont) %s", h2e->name); Lck_Unlock(&h2->sess->mtx); - (void)h2h_decode_fini(h2, r2->decode); - FREE_OBJ(r2->decode); + (void)h2h_decode_fini(h2); AZ(r2->req->ws->r); h2_del_req(wrk, r2); return (h2e); diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index c0545265c..40a111754 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -97,7 +97,7 @@ h2_local_settings(struct h2_settings *h2s) static struct h2_sess * h2_init_sess(const struct worker *wrk, struct sess *sp, - struct h2_sess *h2s, struct req *srq) + struct h2_sess *h2s, struct req *srq, struct h2h_decode *decode) { uintptr_t *up; struct h2_sess *h2; @@ -128,6 +128,7 @@ h2_init_sess(const struct worker *wrk, struct sess *sp, VTAILQ_INIT(&h2->txqueue); h2_local_settings(&h2->local_settings); h2->remote_settings = H2_proto_settings; + h2->decode = decode; AZ(VHT_Init(h2->dectbl, h2->local_settings.header_table_size)); @@ -338,6 +339,7 @@ h2_new_session(struct worker *wrk, void *arg) struct h2_req *r2, *r22; int again; uint8_t settings[48]; + struct h2h_decode decode; size_t l; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -350,7 +352,7 @@ h2_new_session(struct worker *wrk, void *arg) assert (req->err_code == H2_PU_MARKER || req->err_code == H2_OU_MARKER); h2 = h2_init_sess(wrk, sp, &h2s, - req->err_code == H2_PU_MARKER ? req : NULL); + req->err_code == H2_PU_MARKER ? req : NULL, &decode); h2->req0 = h2_new_req(wrk, h2, 0, NULL); AZ(h2->htc->priv); h2->htc->priv = h2; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] dcbc80c6b reshuffle HSH_Lookup() code a bit to condense and clarify Message-ID: <20180816085317.C70709C1FA@lists.varnish-cache.org> commit dcbc80c6b3669858c0eed90044b8d96c59587ae3 Author: Nils Goroll Date: Tue Jun 19 17:02:36 2018 +0200 reshuffle HSH_Lookup() code a bit to condense and clarify With the req.grace reintroduction, we got two identical cases where we insert a busy object: When there is no exp_oc (obviously) or when the exp_oc does not fulfil the req.grace limit. This lead to some code duplication. IMHO, handling first the case where we need to insert a busy object (with or without exp_oc) and then handling the exception that we do not wait on a busy object if the exp_oc is in grace is cleaner. Please note that comparing this change using diff -u does not make much sense, I believe the simplicity of the reshuffling change becomes clear when looking at the old and new code side-by-side diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 38531b149..3fbbc702d 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -478,58 +478,45 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp, busy_found = 0; } - if (exp_oc != NULL && EXP_Ttl_grace(req, exp_oc) < req->t_req) { - /* the newest object is out of grace */ - if (!busy_found) { - /* - * here we get to insert the busy object. This - * translates to a MISS with a 304 candidate. - */ + if (!busy_found) { + /* Insert objcore in objecthead */ + *bocp = hsh_insert_busyobj(wrk, oh); + + if (exp_oc != NULL) { assert(oh->refcnt > 1); assert(exp_oc->objhead == oh); exp_oc->refcnt++; - /* Insert objcore in objecthead and release mutex */ - *bocp = hsh_insert_busyobj(wrk, oh); - /* NB: no deref of objhead, new object inherits reference */ Lck_Unlock(&oh->mtx); *ocp = exp_oc; - return (HSH_MISS); + + if (EXP_Ttl_grace(req, exp_oc) < req->t_req) { + retval = HSH_MISS; + } else { + if (exp_oc->hits < LONG_MAX) + exp_oc->hits++; + retval = HSH_EXPBUSY; + } } else { - /* we have no use for this very expired object */ - exp_oc = NULL; + Lck_Unlock(&oh->mtx); + retval = HSH_MISS; } + + return (retval); } - if (exp_oc != NULL) { - /* - * here the object is within grace, so we expect it to - * be delivered - */ + + AN(busy_found); + if (exp_oc != NULL && EXP_Ttl_grace(req, exp_oc) >= req->t_req) { + /* we do not wait on the busy object if in grace */ assert(oh->refcnt > 1); assert(exp_oc->objhead == oh); exp_oc->refcnt++; - - if (!busy_found) { - *bocp = hsh_insert_busyobj(wrk, oh); - retval = HSH_EXPBUSY; - } else { - AZ(req->hash_ignore_busy); - retval = HSH_EXP; - } - if (exp_oc->hits < LONG_MAX) - exp_oc->hits++; Lck_Unlock(&oh->mtx); - if (retval == HSH_EXP) - assert(HSH_DerefObjHead(wrk, &oh)); *ocp = exp_oc; - return (retval); - } - if (!busy_found) { - /* Insert objcore in objecthead and release mutex */ - *bocp = hsh_insert_busyobj(wrk, oh); - /* NB: no deref of objhead, new object inherits reference */ - Lck_Unlock(&oh->mtx); - return (HSH_MISS); + assert(HSH_DerefObjHead(wrk, &oh)); + if (exp_oc->hits < LONG_MAX) + exp_oc->hits++; + return (HSH_EXP); } /* There are one or more busy objects, wait for them */ From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] ca4102aef Set the mode on the UDS socket, in case we are running as root with varnish user etc. Message-ID: <20180816085317.EDF289C215@lists.varnish-cache.org> commit ca4102aefd6e80ad8c80043884d0c7313a99c661 Author: Poul-Henning Kamp Date: Mon Jul 2 14:45:22 2018 +0000 Set the mode on the UDS socket, in case we are running as root with varnish user etc. diff --git a/bin/varnishtest/tests/r02702.vtc b/bin/varnishtest/tests/r02702.vtc index 6208f0c07..c9a938a90 100644 --- a/bin/varnishtest/tests/r02702.vtc +++ b/bin/varnishtest/tests/r02702.vtc @@ -41,7 +41,7 @@ server s2 { txresp } -start -varnish v2 -arg "-a ${tmpdir}/v2.sock,PROXY" -vcl { +varnish v2 -arg "-a ${tmpdir}/v2.sock,PROXY,mode=0777" -vcl { backend s2 { .host = "${s2_addr}"; .port = "${s2_port}"; } } -start From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:18 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:18 +0000 (UTC) Subject: [6.0] 88a4743d1 Make sure the expiry is in the VSL before proceeding Message-ID: <20180816085318.204099C226@lists.varnish-cache.org> commit 88a4743d1c17f00450c311b646483f95119ae0a4 Author: Poul-Henning Kamp Date: Mon Jul 2 15:34:05 2018 +0000 Make sure the expiry is in the VSL before proceeding diff --git a/bin/varnishtest/tests/b00063.vtc b/bin/varnishtest/tests/b00063.vtc index 1adfe2680..7a68e2e2f 100644 --- a/bin/varnishtest/tests/b00063.vtc +++ b/bin/varnishtest/tests/b00063.vtc @@ -45,6 +45,12 @@ varnish v1 -vcl+backend { } } -start +logexpect l1 -v v1 -g raw { + expect * * ExpKill EXP_expire + expect * * ExpKill EXP_When + expect * * ExpKill EXP_expire +} -start + client c1 { txreq -url "/1" rxresp @@ -76,6 +82,9 @@ client c2 { client c1 -wait client c2 -wait +# Make sure the expiry has happened +logexpect l1 -wait + client c3 { delay .1 # We should now get a HIT on the 404: From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:18 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:18 +0000 (UTC) Subject: [6.0] f493f2b10 Remember to zero h2->mailcall on h2 rxbody vfp failure Message-ID: <20180816085318.46EC09C245@lists.varnish-cache.org> commit f493f2b107e5e3f7f25ca0684b7cbc98c8d2d35b Author: Dag Haavi Finstad Date: Tue Jul 3 16:05:00 2018 +0200 Remember to zero h2->mailcall on h2 rxbody vfp failure Fixes: #2572 diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index f4cc294e5..3851089cd 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -835,8 +835,10 @@ h2_vfp_body_fini(struct vfp_ctx *vc, struct vfp_entry *vfe) H2SE_REFUSED_STREAM); Lck_Lock(&h2->sess->mtx); r2->error = H2SE_REFUSED_STREAM; - if (h2->mailcall == r2) + if (h2->mailcall == r2) { + h2->mailcall = NULL; AZ(pthread_cond_signal(h2->cond)); + } Lck_Unlock(&h2->sess->mtx); } } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:18 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:18 +0000 (UTC) Subject: [6.0] f1ddfb935 Polish Message-ID: <20180816085318.6ED899C251@lists.varnish-cache.org> commit f1ddfb935f0d0dfcc52446e261d91eb69eb7f471 Author: Federico G. Schwindt Date: Tue Jul 3 19:29:06 2018 +0100 Polish diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 08bddf833..31fa31773 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -256,18 +256,15 @@ vbp_write_proxy_v1(struct vbp_target *vt, int *sock) VTCP_myname(*sock, addr, sizeof addr, port, sizeof port); AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN)); - AZ(VSB_cat(&vsb, "PROXY")); l = sizeof ss; AZ(getsockname(*sock, (void *)&ss, &l)); - if (ss.ss_family == AF_INET6) - VSB_printf(&vsb, " TCP6 "); - else if (ss.ss_family == AF_INET) - VSB_printf(&vsb, " TCP4 "); - else - VSB_printf(&vsb, " UNKNOWN\r\n"); - if (ss.ss_family == AF_INET6 || ss.ss_family == AF_INET) - VSB_printf(&vsb, "%s %s %s %s\r\n", addr, addr, port, port); + if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) { + VSB_printf(&vsb, "PROXY %s %s %s %s %s\r\n", + ss.ss_family == AF_INET ? "TCP4" : "TCP6", + addr, addr, port, port); + } else + VSB_cat(&vsb, "PROXY UNKNOWN\r\n"); AZ(VSB_finish(&vsb)); return (vbp_write(vt, sock, VSB_data(&vsb), VSB_len(&vsb))); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:18 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:18 +0000 (UTC) Subject: [6.0] 6c8fed902 Revert "Terminate varnishtop -d automatically" Message-ID: <20180816085318.935689C26E@lists.varnish-cache.org> commit 6c8fed90260be75f618aab734e066aee89e4e4ec Author: Dridi Boukelmoune Date: Wed Jul 4 16:14:39 2018 +0200 Revert "Terminate varnishtop -d automatically" This reverts commit d1b78e8d13a993931d19f2c11acd19959e258ce9. The problem is that upon exiting the screen is likely to be cleared on most terminals (not the one we embed in varnishtest for example) so it doesn't give any chance to the user to read the output. The consensus is to restore the previous behavior and fix the manual instead. Conflicts: bin/varnishtest/tests/u00004.vtc bin/varnishtop/varnishtop.c Breaks: bin/varnishtest/tests/r02686.vtc Refs #2721 diff --git a/bin/varnishtest/tests/r02686.vtc b/bin/varnishtest/tests/r02686.vtc index eb85b9914..a58a4f545 100644 --- a/bin/varnishtest/tests/r02686.vtc +++ b/bin/varnishtest/tests/r02686.vtc @@ -18,7 +18,7 @@ delay 2 process p1 -expect-text 1 1 "list length 1" process p1 -expect-text 1 75 "(EOF)" process p1 -expect-text 3 6 "1.00 ReqMethod GET" -process p1 -screen_dump -wait +process p1 -screen_dump -write q -wait process p2 -dump {varnishtop -n ${v1_name} -1 -i ReqMethod} -start process p2 -winsz 30 80 diff --git a/bin/varnishtest/tests/u00004.vtc b/bin/varnishtest/tests/u00004.vtc index 5435f9865..5dfaa3310 100644 --- a/bin/varnishtest/tests/u00004.vtc +++ b/bin/varnishtest/tests/u00004.vtc @@ -14,8 +14,10 @@ client c1 { shell -expect "fetch" "varnishtop -n ${v1_name} -1" -process p1 "varnishtop -n ${v1_name} -d" -run -screen_dump -process p1 -expect-text 0 0 fetch +process p1 "varnishtop -n ${v1_name} -d" -start +delay 1 +process p1 -screen_dump -expect-text 0 0 fetch +process p1 -write q -wait # without -f shell -match "1\\.00 RespHeader Date: [^\\n]+\\n" { diff --git a/bin/varnishtop/varnishtop.c b/bin/varnishtop/varnishtop.c index ba4b01e6b..0550f8abc 100644 --- a/bin/varnishtop/varnishtop.c +++ b/bin/varnishtop/varnishtop.c @@ -77,13 +77,13 @@ struct top { }; static int period = 60; /* seconds */ +static int end_of_file = 0; static unsigned ntop; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static int f_flag = 0; static unsigned maxfieldlen = 0; static const char *ident; -static volatile sig_atomic_t end_of_file = 0; static volatile sig_atomic_t quit = 0; static VRB_HEAD(t_order, top) h_order = VRB_INITIALIZER(&h_order); @@ -204,7 +204,7 @@ static void update(int p) { struct top *tp, *tp2; - int l, len, eof; + int l, len; double t = 0; static time_t last = 0; static unsigned n = 0; @@ -222,8 +222,7 @@ update(int p) AC(erase()); q = ident; len = COLS - strlen(q); - eof = end_of_file; - if (eof) + if (end_of_file) AC(mvprintw(0, len - (1 + 6), "%s (EOF)", q)); else AC(mvprintw(0, len - 1, "%s", q)); @@ -241,7 +240,7 @@ update(int p) len, len, tp->rec_data)); t = tp->count; } - if (eof) + if (end_of_file) continue; tp->count += (1.0/3.0 - tp->count) / (double)n; if (tp->count * 10 < t || l > LINES * 10) { @@ -253,8 +252,6 @@ update(int p) } } AC(refresh()); - if (eof) - quit = 1; } static void * From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:18 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:18 +0000 (UTC) Subject: [6.0] dadff02b9 varnishtop -d does not exit by itself Message-ID: <20180816085318.B77329C278@lists.varnish-cache.org> commit dadff02b91f75558fb92c7e1b58013dc0bdb0a69 Author: Dridi Boukelmoune Date: Wed Jul 4 16:19:15 2018 +0200 varnishtop -d does not exit by itself Unless -1 is used too, but -1 already implies -d so it doesn't really count. Fixes #2721 diff --git a/bin/varnishtop/varnishtop_options.h b/bin/varnishtop/varnishtop_options.h index ebf8912c1..6605d463a 100644 --- a/bin/varnishtop/varnishtop_options.h +++ b/bin/varnishtop/varnishtop_options.h @@ -37,6 +37,11 @@ " statistics once and exit. Implies ``-d``." \ ) +#define TOP_OPT_d \ + VOPT("d", "[-d]", "Process old log entries", \ + "Process log records at the head of the log." \ + ) + #define TOP_OPT_f \ VOPT("f", "[-f]", "First field only", \ "Sort and group only on the first field of each log entry." \ @@ -59,7 +64,7 @@ TOP_OPT_1 VSL_OPT_b VSL_OPT_c VSL_OPT_C -VUT_OPT_d +TOP_OPT_d TOP_OPT_f VUT_OPT_g VUT_OPT_h From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:18 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:18 +0000 (UTC) Subject: [6.0] 25e028f2b Postpone conversion to BOOL until we absolutely have to. Message-ID: <20180816085318.DB8FA9C296@lists.varnish-cache.org> commit 25e028f2b1995a03ff3d703b5e3558911272de74 Author: Poul-Henning Kamp Date: Wed Jul 11 21:28:18 2018 +0000 Postpone conversion to BOOL until we absolutely have to. Fixes 2727 diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index ee2f2a22d..60e1fb346 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -277,11 +277,45 @@ varnish v1 -errvcl {Comparison of different types: BACKEND '==' STRING} { } } +varnish v1 -errvcl {'!' must be followed by BOOL, found REAL.} { + import std; + sub vcl_recv { if (!std.random(0,1)) { } } +} + +varnish v1 -errvcl {'&&' must be followed by BOOL, found REAL.} { + import std; + sub vcl_recv { if (0 && std.random(0,1)) { } } +} + +varnish v1 -errvcl {'||' must be followed by BOOL, found REAL.} { + import std; + sub vcl_recv { if (0 || std.random(0,1)) { } } +} + +varnish v1 -errvcl {'&&' must be preceeded by BOOL, found REAL.} { + import std; + sub vcl_recv { if (std.random(0,1) && 0) { } } +} + +varnish v1 -errvcl {'||' must be preceeded by BOOL, found REAL.} { + import std; + sub vcl_recv { if (std.random(0,1) || 0) { } } +} + server s1 { rxreq txresp -hdr "bar: X" } -start +varnish v1 -vcl+backend { + // Ticket 2727 + sub vcl_recv { + if ((2 - 1) > 0) { + # nothing + } + } +} + varnish v1 -vcl+backend { sub vcl_deliver { set resp.http.foo = diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index e5ef67416..b9ad25a8e 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -246,6 +246,28 @@ vcc_expr_fmt(struct vsb *d, int ind, const struct expr *e1) } } +/*-------------------------------------------------------------------- + */ + +static void +vcc_expr_tobool(struct vcc *tl, struct expr **e) +{ + + if ((*e)->fmt == BOOL) + return; + if ((*e)->fmt == BACKEND || (*e)->fmt == INT) + *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL); + else if ((*e)->fmt == DURATION) + *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL); + else if ((*e)->fmt == STRINGS) + *e = vcc_expr_edit(tl, BOOL, "(\vS != 0)", *e, NULL); + /* + * We do not provide automatic folding from REAL to BOOL + * because comparing to zero is seldom an exact science + * and we want to force people to explicitly get it right. + */ +} + /*-------------------------------------------------------------------- */ @@ -1126,16 +1148,6 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt) default: break; } - if (fmt != BOOL) - return; - if ((*e)->fmt == BACKEND || (*e)->fmt == INT) - *e = vcc_expr_edit(tl, BOOL, "(\v1 != 0)", *e, NULL); - else if ((*e)->fmt == DURATION) - *e = vcc_expr_edit(tl, BOOL, "(\v1 > 0)", *e, NULL); - else if ((*e)->fmt == STRINGS) - *e = vcc_expr_edit(tl, BOOL, "(\vS != 0)", *e, NULL); - else - INCOMPL(); } /*-------------------------------------------------------------------- @@ -1147,63 +1159,92 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt) static void vcc_expr_not(struct vcc *tl, struct expr **e, vcc_type_t fmt) { - struct expr *e2; struct token *tk; *e = NULL; - if (fmt != BOOL || tl->t->tok != '!') { - vcc_expr_cmp(tl, e, fmt); - return; - } - - vcc_NextToken(tl); tk = tl->t; - vcc_expr_cmp(tl, &e2, fmt); + if (tl->t->tok == '!') + vcc_NextToken(tl); + vcc_expr_cmp(tl, e, fmt); ERRCHK(tl); - if (e2->fmt != BOOL) { + if (tk->tok != '!') + return; + vcc_expr_tobool(tl, e); + ERRCHK(tl); + if ((*e)->fmt != BOOL) { VSB_printf(tl->sb, "'!' must be followed by BOOL, found "); - VSB_printf(tl->sb, "%s.\n", vcc_utype(e2->fmt)); + VSB_printf(tl->sb, "%s.\n", vcc_utype((*e)->fmt)); vcc_ErrWhere2(tl, tk, tl->t); } else { - *e = vcc_expr_edit(tl, BOOL, "!(\v1)", e2, NULL); + *e = vcc_expr_edit(tl, BOOL, "!(\v1)", *e, NULL); } } /*-------------------------------------------------------------------- - * SYNTAX: - * ExprCand: - * ExprNot { '&&' ExprNot } * + * CAND and COR are identical save for a few details, but they are + * stacked so handling them in the same function is not simpler. + * Instead have them both call this helper function to do everything. */ +typedef void upfunc(struct vcc *tl, struct expr **e, vcc_type_t fmt); + static void -vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt) +vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt, + unsigned ourtok, upfunc *up, const char *tokstr) { struct expr *e2; struct token *tk; + char buf[32]; *e = NULL; - vcc_expr_not(tl, e, fmt); + tk = tl->t; + up(tl, e, fmt); ERRCHK(tl); - if ((*e)->fmt != BOOL || tl->t->tok != T_CAND) + if (tl->t->tok != ourtok) return; + vcc_expr_tobool(tl, e); + ERRCHK(tl); + if ((*e)->fmt != BOOL) { + VSB_printf(tl->sb, + "'%s' must be preceeded by BOOL," + " found %s.\n", tokstr, vcc_utype((*e)->fmt)); + vcc_ErrWhere2(tl, tk, tl->t); + return; + } *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL); - while (tl->t->tok == T_CAND) { + while (tl->t->tok == ourtok) { vcc_NextToken(tl); tk = tl->t; vcc_expr_not(tl, &e2, fmt); ERRCHK(tl); + vcc_expr_tobool(tl, &e2); + ERRCHK(tl); if (e2->fmt != BOOL) { VSB_printf(tl->sb, - "'&&' must be followed by BOOL," - " found %s.\n", vcc_utype(e2->fmt)); + "'%s' must be followed by BOOL," + " found %s.\n", tokstr, vcc_utype(e2->fmt)); vcc_ErrWhere2(tl, tk, tl->t); return; } - *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n&&\v+\n\v2", *e, e2); + bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr); + *e = vcc_expr_edit(tl, BOOL, buf, *e, e2); } *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL); } +/*-------------------------------------------------------------------- + * SYNTAX: + * ExprCand: + * ExprNot { '&&' ExprNot } * + */ + +static void +vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt) +{ + + vcc_expr_bin_bool(tl, e, fmt, T_CAND, vcc_expr_not, "&&"); +} + /*-------------------------------------------------------------------- * SYNTAX: * ExprCOR: @@ -1213,30 +1254,8 @@ vcc_expr_cand(struct vcc *tl, struct expr **e, vcc_type_t fmt) static void vcc_expr_cor(struct vcc *tl, struct expr **e, vcc_type_t fmt) { - struct expr *e2; - struct token *tk; - *e = NULL; - vcc_expr_cand(tl, e, fmt); - ERRCHK(tl); - if ((*e)->fmt != BOOL || tl->t->tok != T_COR) - return; - *e = vcc_expr_edit(tl, BOOL, "(\v+\n\v1", *e, NULL); - while (tl->t->tok == T_COR) { - vcc_NextToken(tl); - tk = tl->t; - vcc_expr_cand(tl, &e2, fmt); - ERRCHK(tl); - if (e2->fmt != BOOL) { - VSB_printf(tl->sb, - "'||' must be followed by BOOL," - " found %s.\n", vcc_utype(e2->fmt)); - vcc_ErrWhere2(tl, tk, tl->t); - return; - } - *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n||\v+\n\v2", *e, e2); - } - *e = vcc_expr_edit(tl, BOOL, "\v1\v-\n)", *e, NULL); + vcc_expr_bin_bool(tl, e, fmt, T_COR, vcc_expr_cand, "||"); } /*-------------------------------------------------------------------- @@ -1274,6 +1293,11 @@ vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt) *e = vcc_expr_edit(tl, STRING_LIST, "\v+\n\v1,\nvrt_magic_string_end\v-", *e, NULL); + if (fmt == BOOL) { + vcc_expr_tobool(tl, e); + ERRCHK(tl); + } + if (fmt != (*e)->fmt) { VSB_printf(tl->sb, "Expression has type %s, expected %s\n", vcc_utype((*e)->fmt), vcc_utype(fmt)); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] dd5ea4a22 Set the task arguments under the lock Message-ID: <20180816085319.143809C2A6@lists.varnish-cache.org> commit dd5ea4a221c8783fd24de1531f3679213322b2c6 Author: Federico G. Schwindt Date: Fri Jul 13 12:02:23 2018 +0100 Set the task arguments under the lock I've been torturing varnish with this change for some time and was not able to reproduce the problem. Should fix #2719. diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c index 2c0ad150f..7cd02533d 100644 --- a/bin/varnishd/cache/cache_wrk.c +++ b/bin/varnishd/cache/cache_wrk.c @@ -214,13 +214,12 @@ Pool_Task_Arg(struct worker *wrk, enum task_prio prio, task_func_t *func, wrk2 = wrk; retval = 0; } - Lck_Unlock(&pp->mtx); AZ(wrk2->task.func); - assert(arg_len <= WS_Reserve(wrk2->aws, arg_len)); memcpy(wrk2->aws->f, arg, arg_len); wrk2->task.func = func; wrk2->task.priv = wrk2->aws->f; + Lck_Unlock(&pp->mtx); if (retval) AZ(pthread_cond_signal(&wrk2->cond)); return (retval); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] 7d6566e77 Set socket options correctly for the accepted socket. Message-ID: <20180816085319.3ADB69C2C9@lists.varnish-cache.org> commit 7d6566e778979c2020ffd8a15f3d62fab6194e24 Author: Geoff Simmons Date: Mon Jul 16 10:29:30 2018 +0200 Set socket options correctly for the accepted socket. Closes #2722 diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index 455697fe1..908613f47 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -221,17 +221,16 @@ vca_tcp_opt_init(void) } static void -vca_tcp_opt_test(const struct listen_sock *ls) +vca_tcp_opt_test(const int sock, const unsigned uds) { - int i, n, sock; + int i, n; struct tcp_opt *to; socklen_t l; void *ptr; - sock = ls->sock; for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && ls->uds) + if (to->iponly && uds) continue; to->need = 1; ptr = calloc(1, to->sz); @@ -247,15 +246,14 @@ vca_tcp_opt_test(const struct listen_sock *ls) } static void -vca_tcp_opt_set(const struct listen_sock *ls, int force) +vca_tcp_opt_set(const int sock, const unsigned uds, const int force) { - int n, sock; + int n; struct tcp_opt *to; - sock = ls->sock; for (n = 0; n < n_tcp_opts; n++) { to = &tcp_opts[n]; - if (to->iponly && ls->uds) + if (to->iponly && uds) continue; if (to->need || force) { VTCP_Assert(setsockopt(sock, @@ -426,10 +424,10 @@ vca_make_session(struct worker *wrk, void *arg) wrk->stats->sess_conn++; if (need_test) { - vca_tcp_opt_test(wa->acceptlsock); + vca_tcp_opt_test(sp->fd, wa->acceptlsock->uds); need_test = 0; } - vca_tcp_opt_set(wa->acceptlsock, 0); + vca_tcp_opt_set(sp->fd, wa->acceptlsock->uds, 0); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); @@ -607,7 +605,7 @@ vca_acct(void *arg) if (ls->sock == -2) continue; // VCA_Shutdown assert (ls->sock > 0); - vca_tcp_opt_set(ls, 1); + vca_tcp_opt_set(ls->sock, ls->uds, 1); } AZ(pthread_mutex_unlock(&shut_mtx)); } @@ -646,7 +644,7 @@ ccf_start(struct cli *cli, const char * const *av, void *priv) ls->endpoint, strerror(errno)); return; } - vca_tcp_opt_set(ls, 1); + vca_tcp_opt_set(ls->sock, ls->uds, 1); if (cache_param->accept_filter) { int i; i = VTCP_filter_http(ls->sock); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] 119a058f1 Increase listen-depth to 100 Message-ID: <20180816085319.5D4919C2D6@lists.varnish-cache.org> commit 119a058f14b272ebef2ee400bd21b8b7fde149e1 Author: Poul-Henning Kamp Date: Tue Jul 17 09:30:34 2018 +0000 Increase listen-depth to 100 Submitted by: Frederic Lecaille diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 3cc12fe28..2de165031 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -389,7 +389,7 @@ haproxy_build_backends(const struct haproxy *h, const char *vsb_data) break; *q++ = '\0'; - sock = VTCP_listen_on("localhost:0", NULL, 1, &err); + sock = VTCP_listen_on("localhost:0", NULL, 100, &err); if (err != NULL) vtc_fatal(h->vl, "Create listen socket failed: %s", err); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] cfd11c1d0 Test some out of workspace conditions for VMOD blob. Message-ID: <20180816085319.800FC9C2EC@lists.varnish-cache.org> commit cfd11c1d0ffa7a22d87d5c24c5b722114d9557ae Author: Geoff Simmons Date: Tue Jul 17 18:10:16 2018 +0200 Test some out of workspace conditions for VMOD blob. To get some better GCOV coverage. So far just IDENTITY encoding. diff --git a/bin/varnishtest/tests/m00049.vtc b/bin/varnishtest/tests/m00049.vtc new file mode 100644 index 000000000..bca702cad --- /dev/null +++ b/bin/varnishtest/tests/m00049.vtc @@ -0,0 +1,97 @@ +varnishtest "VMOD blob workspace overflow conditions" + +varnish v1 -vcl { + import blob; + import vtc; + backend b { .host = "${bad_ip}"; } + + sub vcl_recv { + if (req.url == "/1") { + # Too small for the vmod_priv object. + vtc.workspace_alloc(client, -8); + } + elsif (req.url == "/2") { + # Likely large enough for the vmod_priv object, + # but not enough left over for the decode. + vtc.workspace_alloc(client, -33); + } + elsif (req.url == "/3") { + # Enough for the decode, but not enough left + # over for the encode. + vtc.workspace_alloc(client, -50); + } + set req.http.Decode + = blob.encode(blob=blob.decode(encoded="1234567890")); + } + + sub vcl_miss { + if (req.url == "/4") { + # Enough for the req.hash BLOB (vmod_priv + 32 + # bytes), but not enough left over for the + # encoding. + vtc.workspace_alloc(client, -65); + set req.http.Encode = blob.encode(blob=req.hash); + } + return( synth(200) ); + } +} -start + +logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { + expect 0 * Begin req + expect * = VCL_Error {^vmod blob error: cannot decode, out of space$} + expect * = End +} -start + +client c1 { + txreq -url "/1" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -wait + +logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { + expect 0 * Begin req + expect * = VCL_Error {^vmod blob error: cannot decode, out of space$} + expect * = End +} -start + +client c1 { + txreq -url "/2" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -wait + +logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { + expect 0 * Begin req + expect * = VCL_Error {^vmod blob error: cannot encode, out of space$} + expect * = End +} -start + +client c1 { + txreq -url "/3" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -wait + +logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { + expect 0 * Begin req + expect * = VCL_Error {^vmod blob error: cannot encode, out of space$} + expect * = End +} -start + +client c1 { + txreq -url "/4" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -wait From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] 4086c5d60 Remove logexpect from the tests for VMOD blob out-of-workspace. Message-ID: <20180816085319.A7FEC9C2FA@lists.varnish-cache.org> commit 4086c5d60b24891dbe33273446067eebcec47953 Author: Geoff Simmons Date: Wed Jul 18 10:19:05 2018 +0200 Remove logexpect from the tests for VMOD blob out-of-workspace. On the various platforms, esp 32-bit, workspace may be exhausted before it gets to the VMOD at all, so we can't reliably expect specific error messages. This has nevertheless improved GCOV coverage, which was the goal. diff --git a/bin/varnishtest/tests/m00049.vtc b/bin/varnishtest/tests/m00049.vtc index bca702cad..f94f5afc6 100644 --- a/bin/varnishtest/tests/m00049.vtc +++ b/bin/varnishtest/tests/m00049.vtc @@ -36,12 +36,6 @@ varnish v1 -vcl { } } -start -logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { - expect 0 * Begin req - expect * = VCL_Error {^vmod blob error: cannot decode, out of space$} - expect * = End -} -start - client c1 { txreq -url "/1" rxresp @@ -49,14 +43,6 @@ client c1 { expect resp.reason == "VCL failed" } -run -logexpect l1 -wait - -logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { - expect 0 * Begin req - expect * = VCL_Error {^vmod blob error: cannot decode, out of space$} - expect * = End -} -start - client c1 { txreq -url "/2" rxresp @@ -64,14 +50,6 @@ client c1 { expect resp.reason == "VCL failed" } -run -logexpect l1 -wait - -logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { - expect 0 * Begin req - expect * = VCL_Error {^vmod blob error: cannot encode, out of space$} - expect * = End -} -start - client c1 { txreq -url "/3" rxresp @@ -79,19 +57,9 @@ client c1 { expect resp.reason == "VCL failed" } -run -logexpect l1 -wait - -logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { - expect 0 * Begin req - expect * = VCL_Error {^vmod blob error: cannot encode, out of space$} - expect * = End -} -start - client c1 { txreq -url "/4" rxresp expect resp.status == 503 expect resp.reason == "VCL failed" } -run - -logexpect l1 -wait From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] 7bbd6013c Fix the out-of-workspace tests for VMOD blob. Message-ID: <20180816085319.CE5069C318@lists.varnish-cache.org> commit 7bbd6013c7dbc0177a0ced9588a719e946ac4a0c Author: Geoff Simmons Date: Wed Jul 18 11:40:25 2018 +0200 Fix the out-of-workspace tests for VMOD blob. The error may be status 500 on 32-bit systems. diff --git a/bin/varnishtest/tests/m00049.vtc b/bin/varnishtest/tests/m00049.vtc index f94f5afc6..81e0ff530 100644 --- a/bin/varnishtest/tests/m00049.vtc +++ b/bin/varnishtest/tests/m00049.vtc @@ -39,27 +39,31 @@ varnish v1 -vcl { client c1 { txreq -url "/1" rxresp - expect resp.status == 503 - expect resp.reason == "VCL failed" + expect resp.status >= 500 + expect resp.status <= 503 + expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run client c1 { txreq -url "/2" rxresp - expect resp.status == 503 - expect resp.reason == "VCL failed" + expect resp.status >= 500 + expect resp.status <= 503 + expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run client c1 { txreq -url "/3" rxresp - expect resp.status == 503 - expect resp.reason == "VCL failed" + expect resp.status >= 500 + expect resp.status <= 503 + expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run client c1 { txreq -url "/4" rxresp - expect resp.status == 503 - expect resp.reason == "VCL failed" + expect resp.status >= 500 + expect resp.status <= 503 + expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:19 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:19 +0000 (UTC) Subject: [6.0] 7b3a3a98c VMOD blob out-of-workspace tests with all encoding schemes. Message-ID: <20180816085319.F15EA9C326@lists.varnish-cache.org> commit 7b3a3a98ca917c15c15160fb1eae7c0d0b832d73 Author: Geoff Simmons Date: Wed Jul 18 13:20:31 2018 +0200 VMOD blob out-of-workspace tests with all encoding schemes. diff --git a/bin/varnishtest/tests/m00049.vtc b/bin/varnishtest/tests/m00049.vtc index 81e0ff530..6850ffc26 100644 --- a/bin/varnishtest/tests/m00049.vtc +++ b/bin/varnishtest/tests/m00049.vtc @@ -44,7 +44,7 @@ client c1 { expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run -client c1 { +client c2 { txreq -url "/2" rxresp expect resp.status >= 500 @@ -52,7 +52,7 @@ client c1 { expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run -client c1 { +client c3 { txreq -url "/3" rxresp expect resp.status >= 500 @@ -60,10 +60,104 @@ client c1 { expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run -client c1 { +client c4 { txreq -url "/4" rxresp expect resp.status >= 500 expect resp.status <= 503 expect resp.reason ~ {(?i)^VCL Failed$|^Internal Server Error$} } -run + +# Similar tests with BASE64 encoding +varnish v1 -vcl { + import blob; + import vtc; + backend b { .host = "${bad_ip}"; } + + sub vcl_recv { + if (req.url == "/1") { + vtc.workspace_alloc(client, -33); + } + elsif (req.url == "/2") { + vtc.workspace_alloc(client, -50); + } + set req.http.Decode + = blob.encode(blob=blob.decode(BASE64, + encoded="MTIzNDU2Nzg5MA==")); + } + + sub vcl_miss { + if (req.url == "/3") { + vtc.workspace_alloc(client, -65); + set req.http.Encode + = blob.encode(BASE64, blob=req.hash); + } + return( synth(200) ); + } +} + +client c1 -run +client c2 -run +client c3 -run + +# URL encoding +varnish v1 -vcl { + import blob; + import vtc; + backend b { .host = "${bad_ip}"; } + + sub vcl_recv { + if (req.url == "/1") { + vtc.workspace_alloc(client, -33); + } + elsif (req.url == "/2") { + vtc.workspace_alloc(client, -50); + } + set req.http.Decode + = blob.encode(blob=blob.decode(URL, + encoded="1234567890")); + } + + sub vcl_miss { + if (req.url == "/3") { + vtc.workspace_alloc(client, -65); + set req.http.Encode = blob.encode(URL, blob=req.hash); + } + return( synth(200) ); + } +} + +client c1 -run +client c2 -run +client c3 -run + +# HEX encoding +varnish v1 -vcl { + import blob; + import vtc; + backend b { .host = "${bad_ip}"; } + + sub vcl_recv { + if (req.url == "/1") { + vtc.workspace_alloc(client, -33); + } + elsif (req.url == "/2") { + vtc.workspace_alloc(client, -50); + } + set req.http.Decode + = blob.encode(blob=blob.decode(HEX, + encoded="31323334353637383930")); + } + + sub vcl_miss { + if (req.url == "/3") { + vtc.workspace_alloc(client, -65); + set req.http.Encode = blob.encode(HEX, blob=req.hash); + } + return( synth(200) ); + } +} + +client c1 -run +client c2 -run +client c3 -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:20 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:20 +0000 (UTC) Subject: [6.0] 70878b172 Add an out-of-workspace test for VMOD blob's sub() function. Message-ID: <20180816085320.23ECE9C343@lists.varnish-cache.org> commit 70878b1722981dcb96ad8732a2277d1f48f566df Author: Geoff Simmons Date: Wed Jul 18 14:45:50 2018 +0200 Add an out-of-workspace test for VMOD blob's sub() function. diff --git a/bin/varnishtest/tests/m00049.vtc b/bin/varnishtest/tests/m00049.vtc index 6850ffc26..17ea49e84 100644 --- a/bin/varnishtest/tests/m00049.vtc +++ b/bin/varnishtest/tests/m00049.vtc @@ -161,3 +161,26 @@ varnish v1 -vcl { client c1 -run client c2 -run client c3 -run + +# sub() function +varnish v1 -vcl { + import blob; + import vtc; + backend b { .host = "${bad_ip}"; } + + sub vcl_miss { + if (req.url == "/1") { + # Not enough for req.hash + vmod_priv + vtc.workspace_alloc(client, -65); + } + elsif (req.url == "/2") { + # Not enough for req.hash + vmod_priv + 30 bytes + vtc.workspace_alloc(client, -90); + } + set req.http.Encode = blob.encode(blob=blob.sub(req.hash, 30B)); + return( synth(200) ); + } +} + +client c1 -run +client c2 -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:20 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:20 +0000 (UTC) Subject: [6.0] c4243b113 Retire the WB mini-interface used by VMOD blob. Message-ID: <20180816085320.48B9D9C34F@lists.varnish-cache.org> commit c4243b113298fc595a4cc86f6ea436d18c98e3d5 Author: Geoff Simmons Date: Wed Jul 18 16:16:21 2018 +0200 Retire the WB mini-interface used by VMOD blob. This was a proof of concept for an alternative WS interface -- write incrementally to reserved workspace as an "open buffer". That may be generally useful for Varnish, but for now we return to the usual WS_* idiom. diff --git a/lib/libvmod_blob/Makefile.am b/lib/libvmod_blob/Makefile.am index 2695913a2..fafce9acd 100644 --- a/lib/libvmod_blob/Makefile.am +++ b/lib/libvmod_blob/Makefile.am @@ -9,8 +9,6 @@ libvmod_blob_la_SOURCES = \ hex.h \ hex.c \ url.c \ - wb.h \ - wb.c \ tbl_encodings.h \ tbl_case.h diff --git a/lib/libvmod_blob/vmod_blob.c b/lib/libvmod_blob/vmod_blob.c index a53d8c415..87591fb52 100644 --- a/lib/libvmod_blob/vmod_blob.c +++ b/lib/libvmod_blob/vmod_blob.c @@ -34,7 +34,6 @@ #include "vcc_if.h" #include "vmod_blob.h" -#include "wb.h" struct vmod_blob_blob { unsigned magic; @@ -357,11 +356,11 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...) { enum encoding dec = parse_encoding(decs); va_list ap; - struct wb_s wb; struct vmod_priv *b; char *buf; uintptr_t snap; ssize_t len; + unsigned space; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AENC(dec); @@ -373,33 +372,28 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...) return NULL; } - if (wb_create(ctx->ws, &wb) == NULL) { - WS_Reset(ctx->ws, snap); - ERRNOMEM(ctx, "cannot decode"); - return NULL; - } - buf = wb_buf(&wb); + buf = WS_Front(ctx->ws); + space = WS_Reserve(ctx->ws, 0); if (length <= 0) length = -1; va_start(ap, p); errno = 0; - len = func[dec].decode(dec, buf, wb_space(&wb), length, p, ap); + len = func[dec].decode(dec, buf, space, length, p, ap); va_end(ap); if (len == -1) { err_decode(ctx, p); - wb_reset(&wb); + WS_Release(ctx->ws, 0); WS_Reset(ctx->ws, snap); return NULL; } if (len == 0) { - wb_reset(&wb); + WS_Release(ctx->ws, 0); WS_Reset(ctx->ws, snap); return null_blob; } - wb_advance(&wb, len); - WS_ReleaseP(ctx->ws, wb_buf(&wb)); + WS_Release(ctx->ws, len); b->priv = buf; b->len = len; b->free = NULL; @@ -409,8 +403,10 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...) static VCL_STRING encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b) { - struct wb_s wb; ssize_t len; + char *buf; + uintptr_t snap; + unsigned space; AENC(enc); @@ -418,25 +414,25 @@ encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b) return NULL; CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); - if (wb_create(ctx->ws, &wb) == NULL) { - ERRNOMEM(ctx, "cannot encode"); - return NULL; - } + snap = WS_Snapshot(ctx->ws); + buf = WS_Front(ctx->ws); + space = WS_Reserve(ctx->ws, 0); - len = func[enc].encode(enc, kase, - wb_buf(&wb), wb_space(&wb), b->priv, b->len); + len = func[enc].encode(enc, kase, buf, space, b->priv, b->len); if (len == -1) { ERRNOMEM(ctx, "cannot encode"); - wb_reset(&wb); + WS_Release(ctx->ws, 0); + WS_Reset(ctx->ws, snap); return NULL; } if (len == 0) { - wb_reset(&wb); + WS_Release(ctx->ws, 0); + WS_Reset(ctx->ws, snap); return ""; } - wb_advance(&wb, len); - return wb_finish(&wb, NULL); + WS_Release(ctx->ws, len + 1); + return buf; } VCL_STRING v_matchproto_(td_blob_encode) diff --git a/lib/libvmod_blob/wb.c b/lib/libvmod_blob/wb.c deleted file mode 100644 index 1b54b3e72..000000000 --- a/lib/libvmod_blob/wb.c +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * Copyright 2015 UPLEX - Nils Goroll Systemoptimierung - * All rights reserved. - * - * Authors: Nils Goroll - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * write buffer: utility functions to append-write on a varnish workspace - */ - -#include "config.h" - -#include - -#include "cache/cache.h" -#include "wb.h" - -char * -wb_create(struct ws *ws, struct wb_s *wb) -{ - if (WS_Reserve(ws, 0) == 0) { - WS_Release(ws, 0); - wb->w = NULL; - wb->ws = NULL; - return NULL; - } - wb->w = ws->f; - wb->ws = ws; - - return wb->w; -} - -void -wb_reset(struct wb_s *wb) -{ - WS_Release(wb->ws, 0); - memset(wb, 0, sizeof(*wb)); -} - -/* - * release varnish workspace - * - * return start of buffer - */ -char * -wb_finish(struct wb_s *wb, ssize_t *l) -{ - char *r = wb->ws->f; - assert(wb->ws->r - wb->w > 0); - if (l) - *l = wb_len(wb); - - *wb->w = '\0'; - wb->w++; - - /* amount of space used */ - WS_ReleaseP(wb->ws, wb->w); - - return r; -} diff --git a/lib/libvmod_blob/wb.h b/lib/libvmod_blob/wb.h deleted file mode 100644 index e2c820d50..000000000 --- a/lib/libvmod_blob/wb.h +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung - * All rights reserved. - * - * Author: Nils Goroll - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -struct wb_s { - struct ws *ws; // varnish workspace - char *w; // current write position -}; - -/* return one byte less for the final zero byte */ -static inline const char* -wb_end(const struct wb_s *wb) { - return wb->ws->r - 1; -} - -/* return the write position */ -static inline char* -wb_buf(const struct wb_s *wb) { - return wb->w; -} - -/* return one byte less for the final zero byte */ -static inline ssize_t -wb_space(const struct wb_s *wb) { - ssize_t f = wb->ws->r - wb->w; - assert(f > 0); - return f - 1; -} - -static inline ssize_t -wb_len(const struct wb_s *wb) { - ssize_t l = wb->w - wb->ws->f; - assert(l >= 0); - return l; -} - -static inline void -wb_advance(struct wb_s *wb, ssize_t l) { - wb->w += l; // final byte - assert(wb->w < wb_end(wb)); -} - -char *wb_create(struct ws *ws, struct wb_s *wb); -void wb_reset(struct wb_s *wb); -char *wb_finish(struct wb_s *wb, ssize_t *l); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:20 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:20 +0000 (UTC) Subject: [6.0] 4a607fe33 VMOD blob encoder: don't forget the terminating null byte Message-ID: <20180816085320.73FEE9C367@lists.varnish-cache.org> commit 4a607fe33abaca1efeb800fd309cee18202f1d28 Author: Geoff Simmons Date: Wed Jul 18 16:33:39 2018 +0200 VMOD blob encoder: don't forget the terminating null byte diff --git a/lib/libvmod_blob/vmod_blob.c b/lib/libvmod_blob/vmod_blob.c index 87591fb52..632580e91 100644 --- a/lib/libvmod_blob/vmod_blob.c +++ b/lib/libvmod_blob/vmod_blob.c @@ -431,6 +431,7 @@ encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b) WS_Reset(ctx->ws, snap); return ""; } + buf[len] = '\0'; WS_Release(ctx->ws, len + 1); return buf; } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:20 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:20 +0000 (UTC) Subject: [6.0] 7e8bd7468 minor typo in upgrading-6.0.rst Message-ID: <20180816085320.8F4599C374@lists.varnish-cache.org> commit 7e8bd7468d825ddfcc29d0f7436cbb6da9e98a45 Author: Valentin Matei Date: Fri Jul 20 18:30:26 2018 +0300 minor typo in upgrading-6.0.rst diff --git a/doc/sphinx/whats-new/upgrading-6.0.rst b/doc/sphinx/whats-new/upgrading-6.0.rst index eaea169a3..2006a97b1 100644 --- a/doc/sphinx/whats-new/upgrading-6.0.rst +++ b/doc/sphinx/whats-new/upgrading-6.0.rst @@ -584,7 +584,7 @@ community support for those platforms. Services ~~~~~~~~ -As a result we ended up with ended up with systemd-only platforms for +As a result we ended up with systemd-only platforms for the official packages. The old services are still available as we archived them in the ``pkg-varnish-cache`` source tree. This was the occasion to remove differences between Red Hat and Debian derivatives From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:20 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:20 +0000 (UTC) Subject: [6.0] b302a2cf4 Test adding (dynamic) backends with probe to already warm vcl Message-ID: <20180816085321.1F04E9C3A3@lists.varnish-cache.org> commit b302a2cf4d4f3863d4ebe9d8c0d6092e5b401079 Author: Nils Goroll Date: Thu Jul 12 12:53:58 2018 +0200 Test adding (dynamic) backends with probe to already warm vcl this tests d912ffe4f7a5e643275699c94b2722d486fd9e7f Tweaked: bin/varnishtest/tests/d00007.vtc In 6.0 this bug doesn't exist and directors behave slightly differently so the test case needed some adjustments to both show that a backend can be added to an already warm VCL with a probe, and that requests succeed. diff --git a/bin/varnishtest/tests/d00007.vtc b/bin/varnishtest/tests/d00007.vtc index eac4a4d17..b46660787 100644 --- a/bin/varnishtest/tests/d00007.vtc +++ b/bin/varnishtest/tests/d00007.vtc @@ -3,6 +3,10 @@ varnishtest "Test dynamic backends" server s1 { rxreq txresp + close + accept + rxreq + txresp } -start varnish v1 -vcl { @@ -10,11 +14,18 @@ varnish v1 -vcl { backend dummy { .host = "${bad_backend}"; } + probe pr { + .window = 1; + .threshold = 1; + .initial = 1; + } + sub vcl_init { - new s1 = debug.dyn("${s1_addr}", "${s1_port}"); + new s1 = debug.dyn("${bad_backend}", "0"); } sub vcl_recv { + s1.refresh("${s1_addr}", "${s1_port}", pr); set req.backend_hint = s1.backend(); } } -start @@ -26,3 +37,5 @@ client c1 { rxresp expect resp.status == 200 } -run + +server s1 -wait diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc index d6094bcae..3e6b06108 100644 --- a/lib/libvmod_debug/vmod.vcc +++ b/lib/libvmod_debug/vmod.vcc @@ -129,7 +129,7 @@ $Function VOID fail() Function to fail vcl code. (See also: RFC748) -$Object dyn(STRING addr, STRING port) +$Object dyn(STRING addr, STRING port, PROBE probe=0) Dynamically create a single-backend director, addr and port must not be empty. @@ -137,7 +137,7 @@ $Method BACKEND .backend() Return the dynamic backend. -$Method VOID .refresh(STRING addr, STRING port) +$Method VOID .refresh(STRING addr, STRING port, PROBE probe=0) Dynamically refresh & (always!) replace the backend by a new one. diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c index 3603d73e5..338c2518c 100644 --- a/lib/libvmod_debug/vmod_debug_dyn.c +++ b/lib/libvmod_debug/vmod_debug_dyn.c @@ -60,7 +60,7 @@ struct xyzzy_debug_dyn_uds { static void dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, - VCL_STRING addr, VCL_STRING port) + VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) { struct addrinfo hints, *res = NULL; struct suckaddr *sa; @@ -75,6 +75,7 @@ dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, vrt.port = port; vrt.vcl_name = dyn->vcl_name; vrt.hosthdr = addr; + vrt.probe = probe; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; @@ -116,7 +117,7 @@ dyn_dir_init(VRT_CTX, struct xyzzy_debug_dyn *dyn, VCL_VOID xyzzy_dyn__init(VRT_CTX, struct xyzzy_debug_dyn **dynp, - const char *vcl_name, VCL_STRING addr, VCL_STRING port) + const char *vcl_name, VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) { struct xyzzy_debug_dyn *dyn; @@ -139,7 +140,7 @@ xyzzy_dyn__init(VRT_CTX, struct xyzzy_debug_dyn **dynp, AZ(pthread_mutex_init(&dyn->mtx, NULL)); - dyn_dir_init(ctx, dyn, addr, port); + dyn_dir_init(ctx, dyn, addr, port, probe); XXXAN(dyn->dir); *dynp = dyn; } @@ -172,11 +173,11 @@ xyzzy_dyn_backend(VRT_CTX, struct xyzzy_debug_dyn *dyn) VCL_VOID xyzzy_dyn_refresh(VRT_CTX, struct xyzzy_debug_dyn *dyn, - VCL_STRING addr, VCL_STRING port) + VCL_STRING addr, VCL_STRING port, VCL_PROBE probe) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(dyn, VMOD_DEBUG_DYN_MAGIC); - dyn_dir_init(ctx, dyn, addr, port); + dyn_dir_init(ctx, dyn, addr, port, probe); } static int From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:21 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:21 +0000 (UTC) Subject: [6.0] a33aa0481 Update doc Message-ID: <20180816085321.422AF9C3B8@lists.varnish-cache.org> commit a33aa0481630ed033c363de2ac1372f50f02ee09 Author: Valentin Matei Date: Tue Jul 31 12:47:45 2018 +0300 Update doc client content -> client context diff --git a/lib/libvmod_directors/vmod.vcc b/lib/libvmod_directors/vmod.vcc index cc5f9aed2..8fecc08e7 100644 --- a/lib/libvmod_directors/vmod.vcc +++ b/lib/libvmod_directors/vmod.vcc @@ -438,7 +438,7 @@ is _not_ the order given when backends are added. * when called in backend context: Use the varnish hash value as set by `vcl_hash` - * when called in client content: hash `req.url` + * when called in client context: hash `req.url` * `URL`: hash req.url / bereq.url From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:21 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:21 +0000 (UTC) Subject: [6.0] 79bde28a9 [varnishtest] generate the decoding tables Message-ID: <20180816085321.7C7079C3D1@lists.varnish-cache.org> commit 79bde28a92bdaddfd0014db63f2e4daf06124f90 Author: Guillaume Quintard Date: Sun Aug 5 09:55:08 2018 -0700 [varnishtest] generate the decoding tables diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 0deef9cfb..200f43394 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -76,7 +76,8 @@ EXTRA_DIST = $(top_srcdir)/bin/varnishtest/tests/*.vtc \ $(top_srcdir)/bin/varnishtest/tests/README \ $(top_srcdir)/bin/varnishtest/gensequences \ $(top_srcdir)/bin/varnishtest/sequences \ - $(top_srcdir)/bin/varnishtest/teken.3 + $(top_srcdir)/bin/varnishtest/teken.3 \ + huffman_gen.py teken.c: teken_state.h @@ -84,4 +85,8 @@ teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences awk -f $(srcdir)/gensequences $(srcdir)/sequences \ > $(builddir)/teken_state.h +vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h + $(srcdir)/huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ + mv $@_ $@ + CLEANFILES = $(builddir)/teken_state.h diff --git a/bin/varnishtest/huffman_gen.py b/bin/varnishtest/huffman_gen.py new file mode 100755 index 000000000..1486bd41d --- /dev/null +++ b/bin/varnishtest/huffman_gen.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +import re +import sys + +#HPH(0x30, 0x00000000, 5) +regex = re.compile("^HPH\((.{4}), (.{10}), +(.{1,3})\)") + +if len(sys.argv) != 2: + print("{} takes one and only one argument".format(sys.argv[0])) + sys.exit(2) + +class sym: + def __init__(self, bigval, bigvall, chr = 0, esc = None): + self.vall = bigvall % 8 if bigvall % 8 else 8 + self.val = bigval & ((1 << self.vall) - 1) + self.pfx = (bigval >> self.vall)# & 0xff + self.chr = chr + self.esc = esc + +tbls = {} +msl = {} # max sym length + +f = open(sys.argv[1]) +for l in f: + grp = 1 + match = regex.match(l) + if not match: + continue + + chr = int(match.group(grp), 16) + grp += 1 + + val = int(match.group(grp), 16) + grp += 1 + + vall = int(match.group(grp)) + + s = sym(val, vall, chr) + if s.pfx not in tbls: + tbls[s.pfx] = {} + + if (s.val in tbls[s.pfx]): + assert(tbls[s.pfx][s.val].e) + tbls[s.pfx][s.val] = s + + # add the escape entry in the "previous" table + if s.pfx: + pp = s.pfx >> 8 + pv = s.pfx & 0xff + if pp not in tbls: + tbls[pp] = {} + tbls[pp][pv] = sym(pv, 8, 0, "&tbl_{:x}".format(s.pfx)) +f.close() + +# add the EOS case +s = sym(63, 6, 0) +tbls[0xffffff][63] = s + +print('''/* NB: This file is machine generated, DO NOT EDIT! + * edit bin/varnishtest/huffman_input instead + */ + +struct stbl; + +struct ssym { + uint8_t csm; /* bits consumed */ + uint8_t chr; /* character */ + struct stbl *nxt; /* next table */ +}; + +struct stbl { + int msk; + struct ssym *syms; +}; +''') + +for pfx in sorted(tbls.keys(), reverse=True): + msl = max([ x.vall for x in tbls[pfx].values() ]) + for s in tbls[pfx].values(): + s.val = s.val << (msl - s.vall) + + tbl = sorted(tbls[pfx].values(), key= lambda x: x.val) + print("\nstatic struct ssym sym_{:x}_array[] = {{".format(pfx)) + for s in tbl: + for j in range(2 ** (msl - s.vall)): + print(" {} {{{}, {:3d}, {}}},".format( + " "*13 if j else "/* idx {:3d} */".format(s.val + j), + s.vall, s.chr % 256, + s.esc if s.esc else "NULL")) + print('''}}; + +static struct stbl tbl_{:x} = {{ + {}, + sym_{:x}_array +}};'''.format(pfx, msl, pfx)) diff --git a/bin/varnishtest/huffman_input b/bin/varnishtest/huffman_input new file mode 100644 index 000000000..bfde068cd --- /dev/null +++ b/bin/varnishtest/huffman_input @@ -0,0 +1,257 @@ + ( 0) |11111111|11000 1ff8 [13] + ( 1) |11111111|11111111|1011000 7fffd8 [23] + ( 2) |11111111|11111111|11111110|0010 fffffe2 [28] + ( 3) |11111111|11111111|11111110|0011 fffffe3 [28] + ( 4) |11111111|11111111|11111110|0100 fffffe4 [28] + ( 5) |11111111|11111111|11111110|0101 fffffe5 [28] + ( 6) |11111111|11111111|11111110|0110 fffffe6 [28] + ( 7) |11111111|11111111|11111110|0111 fffffe7 [28] + ( 8) |11111111|11111111|11111110|1000 fffffe8 [28] + ( 9) |11111111|11111111|11101010 ffffea [24] + ( 10) |11111111|11111111|11111111|111100 3ffffffc [30] + ( 11) |11111111|11111111|11111110|1001 fffffe9 [28] + ( 12) |11111111|11111111|11111110|1010 fffffea [28] + ( 13) |11111111|11111111|11111111|111101 3ffffffd [30] + ( 14) |11111111|11111111|11111110|1011 fffffeb [28] + ( 15) |11111111|11111111|11111110|1100 fffffec [28] + ( 16) |11111111|11111111|11111110|1101 fffffed [28] + ( 17) |11111111|11111111|11111110|1110 fffffee [28] + ( 18) |11111111|11111111|11111110|1111 fffffef [28] + ( 19) |11111111|11111111|11111111|0000 ffffff0 [28] + ( 20) |11111111|11111111|11111111|0001 ffffff1 [28] + ( 21) |11111111|11111111|11111111|0010 ffffff2 [28] + ( 22) |11111111|11111111|11111111|111110 3ffffffe [30] + ( 23) |11111111|11111111|11111111|0011 ffffff3 [28] + ( 24) |11111111|11111111|11111111|0100 ffffff4 [28] + ( 25) |11111111|11111111|11111111|0101 ffffff5 [28] + ( 26) |11111111|11111111|11111111|0110 ffffff6 [28] + ( 27) |11111111|11111111|11111111|0111 ffffff7 [28] + ( 28) |11111111|11111111|11111111|1000 ffffff8 [28] + ( 29) |11111111|11111111|11111111|1001 ffffff9 [28] + ( 30) |11111111|11111111|11111111|1010 ffffffa [28] + ( 31) |11111111|11111111|11111111|1011 ffffffb [28] + ' ' ( 32) |010100 14 [ 6] + '!' ( 33) |11111110|00 3f8 [10] + '"' ( 34) |11111110|01 3f9 [10] + '#' ( 35) |11111111|1010 ffa [12] + '$' ( 36) |11111111|11001 1ff9 [13] + '%' ( 37) |010101 15 [ 6] + '&' ( 38) |11111000 f8 [ 8] + ''' ( 39) |11111111|010 7fa [11] + '(' ( 40) |11111110|10 3fa [10] + ')' ( 41) |11111110|11 3fb [10] + '*' ( 42) |11111001 f9 [ 8] + '+' ( 43) |11111111|011 7fb [11] + ',' ( 44) |11111010 fa [ 8] + '-' ( 45) |010110 16 [ 6] + '.' ( 46) |010111 17 [ 6] + '/' ( 47) |011000 18 [ 6] + '0' ( 48) |00000 0 [ 5] + '1' ( 49) |00001 1 [ 5] + '2' ( 50) |00010 2 [ 5] + '3' ( 51) |011001 19 [ 6] + '4' ( 52) |011010 1a [ 6] + '5' ( 53) |011011 1b [ 6] + '6' ( 54) |011100 1c [ 6] + '7' ( 55) |011101 1d [ 6] + '8' ( 56) |011110 1e [ 6] + '9' ( 57) |011111 1f [ 6] + ':' ( 58) |1011100 5c [ 7] + ';' ( 59) |11111011 fb [ 8] + '<' ( 60) |11111111|1111100 7ffc [15] + '=' ( 61) |100000 20 [ 6] + '>' ( 62) |11111111|1011 ffb [12] + '?' ( 63) |11111111|00 3fc [10] + '@' ( 64) |11111111|11010 1ffa [13] + 'A' ( 65) |100001 21 [ 6] + 'B' ( 66) |1011101 5d [ 7] + 'C' ( 67) |1011110 5e [ 7] + 'D' ( 68) |1011111 5f [ 7] + 'E' ( 69) |1100000 60 [ 7] + 'F' ( 70) |1100001 61 [ 7] + 'G' ( 71) |1100010 62 [ 7] + 'H' ( 72) |1100011 63 [ 7] + 'I' ( 73) |1100100 64 [ 7] + 'J' ( 74) |1100101 65 [ 7] + 'K' ( 75) |1100110 66 [ 7] + 'L' ( 76) |1100111 67 [ 7] + 'M' ( 77) |1101000 68 [ 7] + 'N' ( 78) |1101001 69 [ 7] + 'O' ( 79) |1101010 6a [ 7] + 'P' ( 80) |1101011 6b [ 7] + 'Q' ( 81) |1101100 6c [ 7] + 'R' ( 82) |1101101 6d [ 7] + 'S' ( 83) |1101110 6e [ 7] + 'T' ( 84) |1101111 6f [ 7] + 'U' ( 85) |1110000 70 [ 7] + 'V' ( 86) |1110001 71 [ 7] + 'W' ( 87) |1110010 72 [ 7] + 'X' ( 88) |11111100 fc [ 8] + 'Y' ( 89) |1110011 73 [ 7] + 'Z' ( 90) |11111101 fd [ 8] + '[' ( 91) |11111111|11011 1ffb [13] + '\' ( 92) |11111111|11111110|000 7fff0 [19] + ']' ( 93) |11111111|11100 1ffc [13] + '^' ( 94) |11111111|111100 3ffc [14] + '_' ( 95) |100010 22 [ 6] + '`' ( 96) |11111111|1111101 7ffd [15] + 'a' ( 97) |00011 3 [ 5] + 'b' ( 98) |100011 23 [ 6] + 'c' ( 99) |00100 4 [ 5] + 'd' (100) |100100 24 [ 6] + 'e' (101) |00101 5 [ 5] + 'f' (102) |100101 25 [ 6] + 'g' (103) |100110 26 [ 6] + 'h' (104) |100111 27 [ 6] + 'i' (105) |00110 6 [ 5] + 'j' (106) |1110100 74 [ 7] + 'k' (107) |1110101 75 [ 7] + 'l' (108) |101000 28 [ 6] + 'm' (109) |101001 29 [ 6] + 'n' (110) |101010 2a [ 6] + 'o' (111) |00111 7 [ 5] + 'p' (112) |101011 2b [ 6] + 'q' (113) |1110110 76 [ 7] + 'r' (114) |101100 2c [ 6] + 's' (115) |01000 8 [ 5] + 't' (116) |01001 9 [ 5] + 'u' (117) |101101 2d [ 6] + 'v' (118) |1110111 77 [ 7] + 'w' (119) |1111000 78 [ 7] + 'x' (120) |1111001 79 [ 7] + 'y' (121) |1111010 7a [ 7] + 'z' (122) |1111011 7b [ 7] + '{' (123) |11111111|1111110 7ffe [15] + '|' (124) |11111111|100 7fc [11] + '}' (125) |11111111|111101 3ffd [14] + '~' (126) |11111111|11101 1ffd [13] + (127) |11111111|11111111|11111111|1100 ffffffc [28] + (128) |11111111|11111110|0110 fffe6 [20] + (129) |11111111|11111111|010010 3fffd2 [22] + (130) |11111111|11111110|0111 fffe7 [20] + (131) |11111111|11111110|1000 fffe8 [20] + (132) |11111111|11111111|010011 3fffd3 [22] + (133) |11111111|11111111|010100 3fffd4 [22] + (134) |11111111|11111111|010101 3fffd5 [22] + (135) |11111111|11111111|1011001 7fffd9 [23] + (136) |11111111|11111111|010110 3fffd6 [22] + (137) |11111111|11111111|1011010 7fffda [23] + (138) |11111111|11111111|1011011 7fffdb [23] + (139) |11111111|11111111|1011100 7fffdc [23] + (140) |11111111|11111111|1011101 7fffdd [23] + (141) |11111111|11111111|1011110 7fffde [23] + (142) |11111111|11111111|11101011 ffffeb [24] + (143) |11111111|11111111|1011111 7fffdf [23] + (144) |11111111|11111111|11101100 ffffec [24] + (145) |11111111|11111111|11101101 ffffed [24] + (146) |11111111|11111111|010111 3fffd7 [22] + (147) |11111111|11111111|1100000 7fffe0 [23] + (148) |11111111|11111111|11101110 ffffee [24] + (149) |11111111|11111111|1100001 7fffe1 [23] + (150) |11111111|11111111|1100010 7fffe2 [23] + (151) |11111111|11111111|1100011 7fffe3 [23] + (152) |11111111|11111111|1100100 7fffe4 [23] + (153) |11111111|11111110|11100 1fffdc [21] + (154) |11111111|11111111|011000 3fffd8 [22] + (155) |11111111|11111111|1100101 7fffe5 [23] + (156) |11111111|11111111|011001 3fffd9 [22] + (157) |11111111|11111111|1100110 7fffe6 [23] + (158) |11111111|11111111|1100111 7fffe7 [23] + (159) |11111111|11111111|11101111 ffffef [24] + (160) |11111111|11111111|011010 3fffda [22] + (161) |11111111|11111110|11101 1fffdd [21] + (162) |11111111|11111110|1001 fffe9 [20] + (163) |11111111|11111111|011011 3fffdb [22] + (164) |11111111|11111111|011100 3fffdc [22] + (165) |11111111|11111111|1101000 7fffe8 [23] + (166) |11111111|11111111|1101001 7fffe9 [23] + (167) |11111111|11111110|11110 1fffde [21] + (168) |11111111|11111111|1101010 7fffea [23] + (169) |11111111|11111111|011101 3fffdd [22] + (170) |11111111|11111111|011110 3fffde [22] + (171) |11111111|11111111|11110000 fffff0 [24] + (172) |11111111|11111110|11111 1fffdf [21] + (173) |11111111|11111111|011111 3fffdf [22] + (174) |11111111|11111111|1101011 7fffeb [23] + (175) |11111111|11111111|1101100 7fffec [23] + (176) |11111111|11111111|00000 1fffe0 [21] + (177) |11111111|11111111|00001 1fffe1 [21] + (178) |11111111|11111111|100000 3fffe0 [22] + (179) |11111111|11111111|00010 1fffe2 [21] + (180) |11111111|11111111|1101101 7fffed [23] + (181) |11111111|11111111|100001 3fffe1 [22] + (182) |11111111|11111111|1101110 7fffee [23] + (183) |11111111|11111111|1101111 7fffef [23] + (184) |11111111|11111110|1010 fffea [20] + (185) |11111111|11111111|100010 3fffe2 [22] + (186) |11111111|11111111|100011 3fffe3 [22] + (187) |11111111|11111111|100100 3fffe4 [22] + (188) |11111111|11111111|1110000 7ffff0 [23] + (189) |11111111|11111111|100101 3fffe5 [22] + (190) |11111111|11111111|100110 3fffe6 [22] + (191) |11111111|11111111|1110001 7ffff1 [23] + (192) |11111111|11111111|11111000|00 3ffffe0 [26] + (193) |11111111|11111111|11111000|01 3ffffe1 [26] + (194) |11111111|11111110|1011 fffeb [20] + (195) |11111111|11111110|001 7fff1 [19] + (196) |11111111|11111111|100111 3fffe7 [22] + (197) |11111111|11111111|1110010 7ffff2 [23] + (198) |11111111|11111111|101000 3fffe8 [22] + (199) |11111111|11111111|11110110|0 1ffffec [25] + (200) |11111111|11111111|11111000|10 3ffffe2 [26] + (201) |11111111|11111111|11111000|11 3ffffe3 [26] + (202) |11111111|11111111|11111001|00 3ffffe4 [26] + (203) |11111111|11111111|11111011|110 7ffffde [27] + (204) |11111111|11111111|11111011|111 7ffffdf [27] + (205) |11111111|11111111|11111001|01 3ffffe5 [26] + (206) |11111111|11111111|11110001 fffff1 [24] + (207) |11111111|11111111|11110110|1 1ffffed [25] + (208) |11111111|11111110|010 7fff2 [19] + (209) |11111111|11111111|00011 1fffe3 [21] + (210) |11111111|11111111|11111001|10 3ffffe6 [26] + (211) |11111111|11111111|11111100|000 7ffffe0 [27] + (212) |11111111|11111111|11111100|001 7ffffe1 [27] + (213) |11111111|11111111|11111001|11 3ffffe7 [26] + (214) |11111111|11111111|11111100|010 7ffffe2 [27] + (215) |11111111|11111111|11110010 fffff2 [24] + (216) |11111111|11111111|00100 1fffe4 [21] + (217) |11111111|11111111|00101 1fffe5 [21] + (218) |11111111|11111111|11111010|00 3ffffe8 [26] + (219) |11111111|11111111|11111010|01 3ffffe9 [26] + (220) |11111111|11111111|11111111|1101 ffffffd [28] + (221) |11111111|11111111|11111100|011 7ffffe3 [27] + (222) |11111111|11111111|11111100|100 7ffffe4 [27] + (223) |11111111|11111111|11111100|101 7ffffe5 [27] + (224) |11111111|11111110|1100 fffec [20] + (225) |11111111|11111111|11110011 fffff3 [24] + (226) |11111111|11111110|1101 fffed [20] + (227) |11111111|11111111|00110 1fffe6 [21] + (228) |11111111|11111111|101001 3fffe9 [22] + (229) |11111111|11111111|00111 1fffe7 [21] + (230) |11111111|11111111|01000 1fffe8 [21] + (231) |11111111|11111111|1110011 7ffff3 [23] + (232) |11111111|11111111|101010 3fffea [22] + (233) |11111111|11111111|101011 3fffeb [22] + (234) |11111111|11111111|11110111|0 1ffffee [25] + (235) |11111111|11111111|11110111|1 1ffffef [25] + (236) |11111111|11111111|11110100 fffff4 [24] + (237) |11111111|11111111|11110101 fffff5 [24] + (238) |11111111|11111111|11111010|10 3ffffea [26] + (239) |11111111|11111111|1110100 7ffff4 [23] + (240) |11111111|11111111|11111010|11 3ffffeb [26] + (241) |11111111|11111111|11111100|110 7ffffe6 [27] + (242) |11111111|11111111|11111011|00 3ffffec [26] + (243) |11111111|11111111|11111011|01 3ffffed [26] + (244) |11111111|11111111|11111100|111 7ffffe7 [27] + (245) |11111111|11111111|11111101|000 7ffffe8 [27] + (246) |11111111|11111111|11111101|001 7ffffe9 [27] + (247) |11111111|11111111|11111101|010 7ffffea [27] + (248) |11111111|11111111|11111101|011 7ffffeb [27] + (249) |11111111|11111111|11111111|1110 ffffffe [28] + (250) |11111111|11111111|11111101|100 7ffffec [27] + (251) |11111111|11111111|11111101|101 7ffffed [27] + (252) |11111111|11111111|11111101|110 7ffffee [27] + (253) |11111111|11111111|11111101|111 7ffffef [27] + (254) |11111111|11111111|11111110|000 7fffff0 [27] + (255) |11111111|11111111|11111011|10 3ffffee [26] + EOS (256) |11111111|11111111|11111111|111111 3fffffff [30] diff --git a/bin/varnishtest/vtc_h2_dectbl.h b/bin/varnishtest/vtc_h2_dectbl.h deleted file mode 100644 index b6402d574..000000000 --- a/bin/varnishtest/vtc_h2_dectbl.h +++ /dev/null @@ -1,1056 +0,0 @@ -struct stbl; - -struct ssym { - uint8_t csm; /* bits consumed */ - uint8_t chr; /* character */ - struct stbl *nxt; /* next table */ -}; - -struct stbl { - int msk; - struct ssym *syms; -}; - -static struct ssym byte3_pref0110_array[] = { - /* idx 0 */ {1, 199, NULL}, - /* idx 1 */ {1, 207, NULL}, -}; - -static struct stbl byte3_pref0110 = { - 1, - byte3_pref0110_array -}; - -static struct ssym byte3_pref0111_array[] = { - /* idx 0 */ {1, 234, NULL}, - /* idx 1 */ {1, 235, NULL}, -}; - -static struct stbl byte3_pref0111 = { - 1, - byte3_pref0111_array -}; - -static struct ssym byte3_pref1000_array[] = { - /* idx 0 */ {2, 192, NULL}, - /* idx 1 */ {2, 193, NULL}, - /* idx 2 */ {2, 200, NULL}, - /* idx 3 */ {2, 201, NULL}, -}; - -static struct stbl byte3_pref1000 = { - 2, - byte3_pref1000_array -}; - -static struct ssym byte3_pref1001_array[] = { - /* idx 0 */ {2, 202, NULL}, - /* idx 1 */ {2, 205, NULL}, - /* idx 2 */ {2, 210, NULL}, - /* idx 3 */ {2, 213, NULL}, -}; - -static struct stbl byte3_pref1001 = { - 2, - byte3_pref1001_array -}; - -static struct ssym byte3_pref1010_array[] = { - /* idx 0 */ {2, 218, NULL}, - /* idx 1 */ {2, 219, NULL}, - /* idx 2 */ {2, 238, NULL}, - /* idx 3 */ {2, 240, NULL}, -}; - -static struct stbl byte3_pref1010 = { - 2, - byte3_pref1010_array -}; - -static struct ssym byte3_pref1011_array[] = { - /* idx 0 */ {2, 242, NULL}, - /* idx 1 */ {2, 242, NULL}, - /* idx 2 */ {2, 243, NULL}, - /* idx 3 */ {2, 243, NULL}, - /* idx 4 */ {2, 255, NULL}, - /* idx 5 */ {2, 255, NULL}, - /* idx 6 */ {3, 203, NULL}, - /* idx 7 */ {3, 204, NULL}, -}; - -static struct stbl byte3_pref1011 = { - 3, - byte3_pref1011_array -}; - -static struct ssym byte3_pref1100_array[] = { - /* idx 0 */ {3, 211, NULL}, - /* idx 1 */ {3, 212, NULL}, - /* idx 2 */ {3, 214, NULL}, - /* idx 3 */ {3, 221, NULL}, - /* idx 4 */ {3, 222, NULL}, - /* idx 5 */ {3, 223, NULL}, - /* idx 6 */ {3, 241, NULL}, - /* idx 7 */ {3, 244, NULL}, -}; - -static struct stbl byte3_pref1100 = { - 3, - byte3_pref1100_array -}; - -static struct ssym byte3_pref1101_array[] = { - /* idx 0 */ {3, 245, NULL}, - /* idx 1 */ {3, 246, NULL}, - /* idx 2 */ {3, 247, NULL}, - /* idx 3 */ {3, 248, NULL}, - /* idx 4 */ {3, 250, NULL}, - /* idx 5 */ {3, 251, NULL}, - /* idx 6 */ {3, 252, NULL}, - /* idx 7 */ {3, 253, NULL}, -}; - -static struct stbl byte3_pref1101 = { - 3, - byte3_pref1101_array -}; - -static struct ssym byte3_pref1110_array[] = { - /* idx 0 */ {3, 254, NULL}, - /* idx 1 */ {3, 254, NULL}, - /* idx 2 */ {4, 2, NULL}, - /* idx 3 */ {4, 3, NULL}, - /* idx 4 */ {4, 4, NULL}, - /* idx 5 */ {4, 5, NULL}, - /* idx 6 */ {4, 6, NULL}, - /* idx 7 */ {4, 7, NULL}, - /* idx 8 */ {4, 8, NULL}, - /* idx 9 */ {4, 11, NULL}, - /* idx 10 */ {4, 12, NULL}, - /* idx 11 */ {4, 14, NULL}, - /* idx 12 */ {4, 15, NULL}, - /* idx 13 */ {4, 16, NULL}, - /* idx 14 */ {4, 17, NULL}, - /* idx 15 */ {4, 18, NULL}, -}; - -static struct stbl byte3_pref1110 = { - 4, - byte3_pref1110_array -}; - -static struct ssym byte3_pref1111_array[] = { - /* idx 0 */ {4, 19, NULL}, - /* idx 1 */ {4, 19, NULL}, - /* idx 2 */ {4, 19, NULL}, - /* idx 3 */ {4, 19, NULL}, - /* idx 4 */ {4, 20, NULL}, - /* idx 5 */ {4, 20, NULL}, - /* idx 6 */ {4, 20, NULL}, - /* idx 7 */ {4, 20, NULL}, - /* idx 8 */ {4, 21, NULL}, - /* idx 9 */ {4, 21, NULL}, - /* idx 10 */ {4, 21, NULL}, - /* idx 11 */ {4, 21, NULL}, - /* idx 12 */ {4, 23, NULL}, - /* idx 13 */ {4, 23, NULL}, - /* idx 14 */ {4, 23, NULL}, - /* idx 15 */ {4, 23, NULL}, - /* idx 16 */ {4, 24, NULL}, - /* idx 17 */ {4, 24, NULL}, - /* idx 18 */ {4, 24, NULL}, - /* idx 19 */ {4, 24, NULL}, - /* idx 20 */ {4, 25, NULL}, - /* idx 21 */ {4, 25, NULL}, - /* idx 22 */ {4, 25, NULL}, - /* idx 23 */ {4, 25, NULL}, - /* idx 24 */ {4, 26, NULL}, - /* idx 25 */ {4, 26, NULL}, - /* idx 26 */ {4, 26, NULL}, - /* idx 27 */ {4, 26, NULL}, - /* idx 28 */ {4, 27, NULL}, - /* idx 29 */ {4, 27, NULL}, - /* idx 30 */ {4, 27, NULL}, - /* idx 31 */ {4, 27, NULL}, - /* idx 32 */ {4, 28, NULL}, - /* idx 33 */ {4, 28, NULL}, - /* idx 34 */ {4, 28, NULL}, - /* idx 35 */ {4, 28, NULL}, - /* idx 36 */ {4, 29, NULL}, - /* idx 37 */ {4, 29, NULL}, - /* idx 38 */ {4, 29, NULL}, - /* idx 39 */ {4, 29, NULL}, - /* idx 40 */ {4, 30, NULL}, - /* idx 41 */ {4, 30, NULL}, - /* idx 42 */ {4, 30, NULL}, - /* idx 43 */ {4, 30, NULL}, - /* idx 44 */ {4, 31, NULL}, - /* idx 45 */ {4, 31, NULL}, - /* idx 46 */ {4, 31, NULL}, - /* idx 47 */ {4, 31, NULL}, - /* idx 48 */ {4, 127, NULL}, - /* idx 49 */ {4, 127, NULL}, - /* idx 50 */ {4, 127, NULL}, - /* idx 51 */ {4, 127, NULL}, - /* idx 52 */ {4, 220, NULL}, - /* idx 53 */ {4, 220, NULL}, - /* idx 54 */ {4, 220, NULL}, - /* idx 55 */ {4, 220, NULL}, - /* idx 56 */ {4, 249, NULL}, - /* idx 57 */ {4, 249, NULL}, - /* idx 58 */ {4, 249, NULL}, - /* idx 59 */ {4, 249, NULL}, - /* idx 60 */ {6, 10, NULL}, - /* idx 61 */ {6, 13, NULL}, - /* idx 62 */ {6, 22, NULL}, - /* idx 63 */ {0, 0, NULL} -}; - -static struct stbl byte3_pref1111 = { - 6, - byte3_pref1111_array -}; - -static struct ssym byte2_pref0_array[] = { - /* idx 0 */ {3, 92, NULL}, /* '\' */ - /* idx 1 */ {3, 92, NULL}, /* '\' */ - /* idx 2 */ {3, 92, NULL}, /* '\' */ - /* idx 3 */ {3, 92, NULL}, /* '\' */ - /* idx 4 */ {3, 195, NULL}, /* . */ - /* idx 5 */ {3, 195, NULL}, /* . */ - /* idx 6 */ {3, 195, NULL}, /* . */ - /* idx 7 */ {3, 195, NULL}, /* . */ - /* idx 8 */ {3, 208, NULL}, /* . */ - /* idx 9 */ {3, 208, NULL}, /* . */ - /* idx 10 */ {3, 208, NULL}, /* . */ - /* idx 11 */ {3, 208, NULL}, /* . */ - /* idx 12 */ {4, 128, NULL}, /* . */ - /* idx 13 */ {4, 128, NULL}, /* . */ - /* idx 14 */ {4, 130, NULL}, /* . */ - /* idx 15 */ {4, 130, NULL}, /* . */ - /* idx 16 */ {4, 131, NULL}, /* . */ - /* idx 17 */ {4, 131, NULL}, /* . */ - /* idx 18 */ {4, 162, NULL}, /* . */ - /* idx 19 */ {4, 162, NULL}, /* . */ - /* idx 20 */ {4, 184, NULL}, /* . */ - /* idx 21 */ {4, 184, NULL}, /* . */ - /* idx 22 */ {4, 194, NULL}, /* . */ - /* idx 23 */ {4, 194, NULL}, /* . */ - /* idx 24 */ {4, 224, NULL}, /* . */ - /* idx 25 */ {4, 224, NULL}, /* . */ - /* idx 26 */ {4, 226, NULL}, /* . */ - /* idx 27 */ {4, 226, NULL}, /* . */ - /* idx 28 */ {5, 153, NULL}, /* . */ - /* idx 29 */ {5, 161, NULL}, /* . */ - /* idx 30 */ {5, 167, NULL}, /* . */ - /* idx 31 */ {5, 172, NULL} /* . */ -}; - -static struct stbl byte2_pref0 = { - 5, - byte2_pref0_array -}; - -static struct ssym byte2_pref1_array[] = { - /* idx 0 */ {5, 176, NULL}, /* . */ - /* idx 1 */ {5, 176, NULL}, /* . */ - /* idx 2 */ {5, 176, NULL}, /* . */ - /* idx 3 */ {5, 176, NULL}, /* . */ - /* idx 4 */ {5, 176, NULL}, /* . */ - /* idx 5 */ {5, 176, NULL}, /* . */ - /* idx 6 */ {5, 176, NULL}, /* . */ - /* idx 7 */ {5, 176, NULL}, /* . */ - /* idx 8 */ {5, 177, NULL}, /* . */ - /* idx 9 */ {5, 177, NULL}, /* . */ - /* idx 10 */ {5, 177, NULL}, /* . */ - /* idx 11 */ {5, 177, NULL}, /* . */ - /* idx 12 */ {5, 177, NULL}, /* . */ - /* idx 13 */ {5, 177, NULL}, /* . */ - /* idx 14 */ {5, 177, NULL}, /* . */ - /* idx 15 */ {5, 177, NULL}, /* . */ - /* idx 16 */ {5, 179, NULL}, /* */ - /* idx 17 */ {5, 179, NULL}, /* */ - /* idx 18 */ {5, 179, NULL}, /* */ - /* idx 19 */ {5, 179, NULL}, /* */ - /* idx 20 */ {5, 179, NULL}, /* */ - /* idx 21 */ {5, 179, NULL}, /* */ - /* idx 22 */ {5, 179, NULL}, /* */ - /* idx 23 */ {5, 179, NULL}, /* */ - /* idx 24 */ {5, 209, NULL}, /* . */ - /* idx 25 */ {5, 209, NULL}, /* . */ - /* idx 26 */ {5, 209, NULL}, /* . */ - /* idx 27 */ {5, 209, NULL}, /* . */ - /* idx 28 */ {5, 209, NULL}, /* . */ - /* idx 29 */ {5, 209, NULL}, /* . */ - /* idx 30 */ {5, 209, NULL}, /* . */ - /* idx 31 */ {5, 209, NULL}, /* . */ - /* idx 32 */ {5, 216, NULL}, /* . */ - /* idx 33 */ {5, 216, NULL}, /* . */ - /* idx 34 */ {5, 216, NULL}, /* . */ - /* idx 35 */ {5, 216, NULL}, /* . */ - /* idx 36 */ {5, 216, NULL}, /* . */ - /* idx 37 */ {5, 216, NULL}, /* . */ - /* idx 38 */ {5, 216, NULL}, /* . */ - /* idx 39 */ {5, 216, NULL}, /* . */ - /* idx 40 */ {5, 217, NULL}, /* . */ - /* idx 41 */ {5, 217, NULL}, /* . */ - /* idx 42 */ {5, 217, NULL}, /* . */ - /* idx 43 */ {5, 217, NULL}, /* . */ - /* idx 44 */ {5, 217, NULL}, /* . */ - /* idx 45 */ {5, 217, NULL}, /* . */ - /* idx 46 */ {5, 217, NULL}, /* . */ - /* idx 47 */ {5, 217, NULL}, /* . */ - /* idx 48 */ {5, 227, NULL}, /* . */ - /* idx 49 */ {5, 227, NULL}, /* . */ - /* idx 50 */ {5, 227, NULL}, /* . */ - /* idx 51 */ {5, 227, NULL}, /* . */ - /* idx 52 */ {5, 227, NULL}, /* . */ - /* idx 53 */ {5, 227, NULL}, /* . */ - /* idx 54 */ {5, 227, NULL}, /* . */ - /* idx 55 */ {5, 227, NULL}, /* . */ - /* idx 56 */ {5, 229, NULL}, /* . */ - /* idx 57 */ {5, 229, NULL}, /* . */ - /* idx 58 */ {5, 229, NULL}, /* . */ - /* idx 59 */ {5, 229, NULL}, /* . */ - /* idx 60 */ {5, 229, NULL}, /* . */ - /* idx 61 */ {5, 229, NULL}, /* . */ - /* idx 62 */ {5, 229, NULL}, /* . */ - /* idx 63 */ {5, 229, NULL}, /* . */ - /* idx 64 */ {5, 230, NULL}, /* . */ - /* idx 65 */ {5, 230, NULL}, /* . */ - /* idx 66 */ {5, 230, NULL}, /* . */ - /* idx 67 */ {5, 230, NULL}, /* . */ - /* idx 68 */ {5, 230, NULL}, /* . */ - /* idx 69 */ {5, 230, NULL}, /* . */ - /* idx 70 */ {5, 230, NULL}, /* . */ - /* idx 71 */ {5, 230, NULL}, /* . */ - /* idx 72 */ {6, 129, NULL}, /* . */ - /* idx 73 */ {6, 129, NULL}, /* . */ - /* idx 74 */ {6, 129, NULL}, /* . */ - /* idx 75 */ {6, 129, NULL}, /* . */ - /* idx 76 */ {6, 132, NULL}, /* . */ - /* idx 77 */ {6, 132, NULL}, /* . */ - /* idx 78 */ {6, 132, NULL}, /* . */ - /* idx 79 */ {6, 132, NULL}, /* . */ - /* idx 80 */ {6, 133, NULL}, /* . */ - /* idx 81 */ {6, 133, NULL}, /* . */ - /* idx 82 */ {6, 133, NULL}, /* . */ - /* idx 83 */ {6, 133, NULL}, /* . */ - /* idx 84 */ {6, 134, NULL}, /* . */ - /* idx 85 */ {6, 134, NULL}, /* . */ - /* idx 86 */ {6, 134, NULL}, /* . */ - /* idx 87 */ {6, 134, NULL}, /* . */ - /* idx 88 */ {6, 136, NULL}, /* . */ - /* idx 89 */ {6, 136, NULL}, /* . */ - /* idx 90 */ {6, 136, NULL}, /* . */ - /* idx 91 */ {6, 136, NULL}, /* . */ - /* idx 92 */ {6, 146, NULL}, /* . */ - /* idx 93 */ {6, 146, NULL}, /* . */ - /* idx 94 */ {6, 146, NULL}, /* . */ - /* idx 95 */ {6, 146, NULL}, /* . */ - /* idx 96 */ {6, 154, NULL}, /* . */ - /* idx 97 */ {6, 154, NULL}, /* . */ - /* idx 98 */ {6, 154, NULL}, /* . */ - /* idx 99 */ {6, 154, NULL}, /* . */ - /* idx 100 */ {6, 156, NULL}, /* . */ - /* idx 101 */ {6, 156, NULL}, /* . */ - /* idx 102 */ {6, 156, NULL}, /* . */ - /* idx 103 */ {6, 156, NULL}, /* . */ - /* idx 104 */ {6, 160, NULL}, /* . */ - /* idx 105 */ {6, 160, NULL}, /* . */ - /* idx 106 */ {6, 160, NULL}, /* . */ - /* idx 107 */ {6, 160, NULL}, /* . */ - /* idx 108 */ {6, 163, NULL}, /* . */ - /* idx 109 */ {6, 163, NULL}, /* . */ - /* idx 110 */ {6, 163, NULL}, /* . */ - /* idx 111 */ {6, 163, NULL}, /* . */ - /* idx 112 */ {6, 164, NULL}, /* . */ - /* idx 113 */ {6, 164, NULL}, /* . */ - /* idx 114 */ {6, 164, NULL}, /* . */ - /* idx 115 */ {6, 164, NULL}, /* . */ - /* idx 116 */ {6, 169, NULL}, /* . */ - /* idx 117 */ {6, 169, NULL}, /* . */ - /* idx 118 */ {6, 169, NULL}, /* . */ - /* idx 119 */ {6, 169, NULL}, /* . */ - /* idx 120 */ {6, 170, NULL}, /* . */ - /* idx 121 */ {6, 170, NULL}, /* . */ - /* idx 122 */ {6, 170, NULL}, /* . */ - /* idx 123 */ {6, 170, NULL}, /* . */ - /* idx 124 */ {6, 173, NULL}, /* . */ - /* idx 125 */ {6, 173, NULL}, /* . */ - /* idx 126 */ {6, 173, NULL}, /* . */ - /* idx 127 */ {6, 173, NULL}, /* . */ - /* idx 128 */ {6, 176, NULL}, /* . */ - /* idx 129 */ {6, 176, NULL}, /* . */ - /* idx 130 */ {6, 176, NULL}, /* . */ - /* idx 131 */ {6, 176, NULL}, /* . */ - /* idx 132 */ {6, 181, NULL}, /* . */ - /* idx 133 */ {6, 181, NULL}, /* . */ - /* idx 134 */ {6, 181, NULL}, /* . */ - /* idx 135 */ {6, 181, NULL}, /* . */ - /* idx 136 */ {6, 185, NULL}, /* . */ - /* idx 137 */ {6, 185, NULL}, /* . */ - /* idx 138 */ {6, 185, NULL}, /* . */ - /* idx 139 */ {6, 185, NULL}, /* . */ - /* idx 140 */ {6, 186, NULL}, /* . */ - /* idx 141 */ {6, 186, NULL}, /* . */ - /* idx 142 */ {6, 186, NULL}, /* . */ - /* idx 143 */ {6, 186, NULL}, /* . */ - /* idx 144 */ {6, 187, NULL}, /* . */ - /* idx 145 */ {6, 187, NULL}, /* . */ - /* idx 146 */ {6, 187, NULL}, /* . */ - /* idx 147 */ {6, 187, NULL}, /* . */ - /* idx 148 */ {6, 189, NULL}, /* . */ - /* idx 149 */ {6, 189, NULL}, /* . */ - /* idx 150 */ {6, 189, NULL}, /* . */ - /* idx 151 */ {6, 189, NULL}, /* . */ - /* idx 152 */ {6, 190, NULL}, /* . */ - /* idx 153 */ {6, 190, NULL}, /* . */ - /* idx 154 */ {6, 190, NULL}, /* . */ - /* idx 155 */ {6, 190, NULL}, /* . */ - /* idx 156 */ {6, 196, NULL}, /* . */ - /* idx 157 */ {6, 196, NULL}, /* . */ - /* idx 158 */ {6, 196, NULL}, /* . */ - /* idx 159 */ {6, 196, NULL}, /* . */ - /* idx 160 */ {6, 198, NULL}, /* . */ - /* idx 161 */ {6, 198, NULL}, /* . */ - /* idx 162 */ {6, 198, NULL}, /* . */ - /* idx 163 */ {6, 198, NULL}, /* . */ - /* idx 164 */ {6, 228, NULL}, /* . */ - /* idx 165 */ {6, 228, NULL}, /* . */ - /* idx 166 */ {6, 228, NULL}, /* . */ - /* idx 167 */ {6, 228, NULL}, /* . */ - /* idx 168 */ {6, 232, NULL}, /* . */ - /* idx 169 */ {6, 232, NULL}, /* . */ - /* idx 170 */ {6, 232, NULL}, /* . */ - /* idx 171 */ {6, 232, NULL}, /* . */ - /* idx 172 */ {6, 233, NULL}, /* . */ - /* idx 173 */ {6, 233, NULL}, /* . */ - /* idx 174 */ {6, 233, NULL}, /* . */ - /* idx 175 */ {6, 233, NULL}, /* . */ - /* idx 176 */ {7, 1, NULL}, - /* idx 177 */ {7, 1, NULL}, - /* idx 178 */ {7, 135, NULL}, - /* idx 179 */ {7, 135, NULL}, - /* idx 180 */ {7, 137, NULL}, - /* idx 181 */ {7, 137, NULL}, - /* idx 182 */ {7, 138, NULL}, - /* idx 183 */ {7, 138, NULL}, - /* idx 184 */ {7, 139, NULL}, - /* idx 185 */ {7, 139, NULL}, - /* idx 186 */ {7, 140, NULL}, - /* idx 187 */ {7, 140, NULL}, - /* idx 188 */ {7, 141, NULL}, - /* idx 189 */ {7, 141, NULL}, - /* idx 190 */ {7, 143, NULL}, - /* idx 191 */ {7, 143, NULL}, - /* idx 192 */ {7, 147, NULL}, - /* idx 193 */ {7, 147, NULL}, - /* idx 194 */ {7, 149, NULL}, - /* idx 195 */ {7, 149, NULL}, - /* idx 196 */ {7, 150, NULL}, - /* idx 197 */ {7, 150, NULL}, - /* idx 198 */ {7, 151, NULL}, - /* idx 199 */ {7, 151, NULL}, - /* idx 200 */ {7, 152, NULL}, - /* idx 201 */ {7, 152, NULL}, - /* idx 202 */ {7, 155, NULL}, - /* idx 203 */ {7, 155, NULL}, - /* idx 204 */ {7, 157, NULL}, - /* idx 205 */ {7, 157, NULL}, - /* idx 206 */ {7, 158, NULL}, - /* idx 207 */ {7, 158, NULL}, - /* idx 208 */ {7, 165, NULL}, - /* idx 209 */ {7, 165, NULL}, - /* idx 210 */ {7, 166, NULL}, - /* idx 211 */ {7, 166, NULL}, - /* idx 212 */ {7, 168, NULL}, - /* idx 213 */ {7, 168, NULL}, - /* idx 214 */ {7, 174, NULL}, - /* idx 215 */ {7, 174, NULL}, - /* idx 216 */ {7, 175, NULL}, - /* idx 217 */ {7, 175, NULL}, - /* idx 218 */ {7, 180, NULL}, - /* idx 219 */ {7, 180, NULL}, - /* idx 220 */ {7, 182, NULL}, - /* idx 221 */ {7, 182, NULL}, - /* idx 222 */ {7, 183, NULL}, - /* idx 223 */ {7, 183, NULL}, - /* idx 224 */ {7, 188, NULL}, - /* idx 225 */ {7, 188, NULL}, - /* idx 226 */ {7, 191, NULL}, - /* idx 227 */ {7, 191, NULL}, - /* idx 228 */ {7, 197, NULL}, - /* idx 229 */ {7, 197, NULL}, - /* idx 230 */ {7, 231, NULL}, - /* idx 231 */ {7, 231, NULL}, - /* idx 232 */ {7, 239, NULL}, - /* idx 233 */ {7, 239, NULL}, - /* idx 234 */ {8, 9, NULL}, /* tab */ - /* idx 235 */ {8, 142, NULL}, - /* idx 236 */ {8, 144, NULL}, - /* idx 237 */ {8, 145, NULL}, - /* idx 238 */ {8, 148, NULL}, - /* idx 239 */ {8, 159, NULL}, - /* idx 240 */ {8, 171, NULL}, - /* idx 241 */ {8, 206, NULL}, - /* idx 242 */ {8, 215, NULL}, - /* idx 243 */ {8, 225, NULL}, - /* idx 244 */ {8, 236, NULL}, - /* idx 245 */ {8, 237, NULL}, - /* idx 246 */ {8, 0, &byte3_pref0110 }, - /* idx 247 */ {8, 0, &byte3_pref0111 }, - /* idx 248 */ {8, 0, &byte3_pref1000 }, - /* idx 249 */ {8, 0, &byte3_pref1001 }, - /* idx 250 */ {8, 0, &byte3_pref1010 }, - /* idx 251 */ {8, 0, &byte3_pref1011 }, - /* idx 252 */ {8, 0, &byte3_pref1100 }, - /* idx 253 */ {8, 0, &byte3_pref1101 }, - /* idx 254 */ {8, 0, &byte3_pref1110 }, - /* idx 255 */ {8, 0, &byte3_pref1111 } -}; - -static struct stbl byte2_pref1 = { - 8, - byte2_pref1_array -}; - -static struct ssym byte1_pref0_array[] = { - /* idx 0 */ {2, 33, NULL}, /* '!' */ - /* idx 1 */ {2, 34, NULL}, /* '"' */ - /* idx 2 */ {2, 40, NULL}, /* '(' */ - /* idx 3 */ {2, 41, NULL}, /* ')' */ -}; - -static struct stbl byte1_pref0 = { - 2, - byte1_pref0_array -}; - -static struct ssym byte1_pref1_array[] = { - /* idx 0 */ {2, 63, NULL}, /* '?' */ - /* idx 1 */ {2, 63, NULL}, /* '?' */ - /* idx 2 */ {2, 63, NULL}, /* '?' */ - /* idx 3 */ {2, 63, NULL}, /* '?' */ - /* idx 4 */ {2, 63, NULL}, /* '?' */ - /* idx 5 */ {2, 63, NULL}, /* '?' */ - /* idx 6 */ {2, 63, NULL}, /* '?' */ - /* idx 7 */ {2, 63, NULL}, /* '?' */ - /* idx 8 */ {2, 63, NULL}, /* '?' */ - /* idx 9 */ {2, 63, NULL}, /* '?' */ - /* idx 10 */ {2, 63, NULL}, /* '?' */ - /* idx 11 */ {2, 63, NULL}, /* '?' */ - /* idx 12 */ {2, 63, NULL}, /* '?' */ - /* idx 13 */ {2, 63, NULL}, /* '?' */ - /* idx 14 */ {2, 63, NULL}, /* '?' */ - /* idx 15 */ {2, 63, NULL}, /* '?' */ - /* idx 16 */ {2, 63, NULL}, /* '?' */ - /* idx 17 */ {2, 63, NULL}, /* '?' */ - /* idx 18 */ {2, 63, NULL}, /* '?' */ - /* idx 19 */ {2, 63, NULL}, /* '?' */ - /* idx 20 */ {2, 63, NULL}, /* '?' */ - /* idx 21 */ {2, 63, NULL}, /* '?' */ - /* idx 22 */ {2, 63, NULL}, /* '?' */ - /* idx 23 */ {2, 63, NULL}, /* '?' */ - /* idx 24 */ {2, 63, NULL}, /* '?' */ - /* idx 25 */ {2, 63, NULL}, /* '?' */ - /* idx 26 */ {2, 63, NULL}, /* '?' */ - /* idx 27 */ {2, 63, NULL}, /* '?' */ - /* idx 28 */ {2, 63, NULL}, /* '?' */ - /* idx 29 */ {2, 63, NULL}, /* '?' */ - /* idx 30 */ {2, 63, NULL}, /* '?' */ - /* idx 31 */ {2, 63, NULL}, /* '?' */ - /* idx 32 */ {2, 63, NULL}, /* '?' */ - /* idx 33 */ {2, 63, NULL}, /* '?' */ - /* idx 34 */ {2, 63, NULL}, /* '?' */ - /* idx 35 */ {2, 63, NULL}, /* '?' */ - /* idx 36 */ {2, 63, NULL}, /* '?' */ - /* idx 37 */ {2, 63, NULL}, /* '?' */ - /* idx 38 */ {2, 63, NULL}, /* '?' */ - /* idx 39 */ {2, 63, NULL}, /* '?' */ - /* idx 40 */ {2, 63, NULL}, /* '?' */ - /* idx 41 */ {2, 63, NULL}, /* '?' */ - /* idx 42 */ {2, 63, NULL}, /* '?' */ - /* idx 43 */ {2, 63, NULL}, /* '?' */ - /* idx 44 */ {2, 63, NULL}, /* '?' */ - /* idx 45 */ {2, 63, NULL}, /* '?' */ - /* idx 46 */ {2, 63, NULL}, /* '?' */ - /* idx 47 */ {2, 63, NULL}, /* '?' */ - /* idx 48 */ {2, 63, NULL}, /* '?' */ - /* idx 49 */ {2, 63, NULL}, /* '?' */ - /* idx 50 */ {2, 63, NULL}, /* '?' */ - /* idx 51 */ {2, 63, NULL}, /* '?' */ - /* idx 52 */ {2, 63, NULL}, /* '?' */ - /* idx 53 */ {2, 63, NULL}, /* '?' */ - /* idx 54 */ {2, 63, NULL}, /* '?' */ - /* idx 55 */ {2, 63, NULL}, /* '?' */ - /* idx 56 */ {2, 63, NULL}, /* '?' */ - /* idx 57 */ {2, 63, NULL}, /* '?' */ - /* idx 58 */ {2, 63, NULL}, /* '?' */ - /* idx 59 */ {2, 63, NULL}, /* '?' */ - /* idx 60 */ {2, 63, NULL}, /* '?' */ - /* idx 61 */ {2, 63, NULL}, /* '?' */ - /* idx 62 */ {2, 63, NULL}, /* '?' */ - /* idx 63 */ {2, 63, NULL}, /* '?' */ - /* idx 64 */ {3, 39, NULL}, /* ''' */ - /* idx 65 */ {3, 39, NULL}, /* ''' */ - /* idx 66 */ {3, 39, NULL}, /* ''' */ - /* idx 67 */ {3, 39, NULL}, /* ''' */ - /* idx 68 */ {3, 39, NULL}, /* ''' */ - /* idx 69 */ {3, 39, NULL}, /* ''' */ - /* idx 70 */ {3, 39, NULL}, /* ''' */ - /* idx 71 */ {3, 39, NULL}, /* ''' */ - /* idx 72 */ {3, 39, NULL}, /* ''' */ - /* idx 73 */ {3, 39, NULL}, /* ''' */ - /* idx 74 */ {3, 39, NULL}, /* ''' */ - /* idx 75 */ {3, 39, NULL}, /* ''' */ - /* idx 76 */ {3, 39, NULL}, /* ''' */ - /* idx 77 */ {3, 39, NULL}, /* ''' */ - /* idx 78 */ {3, 39, NULL}, /* ''' */ - /* idx 79 */ {3, 39, NULL}, /* ''' */ - /* idx 80 */ {3, 39, NULL}, /* ''' */ - /* idx 81 */ {3, 39, NULL}, /* ''' */ - /* idx 82 */ {3, 39, NULL}, /* ''' */ - /* idx 83 */ {3, 39, NULL}, /* ''' */ - /* idx 84 */ {3, 39, NULL}, /* ''' */ - /* idx 85 */ {3, 39, NULL}, /* ''' */ - /* idx 86 */ {3, 39, NULL}, /* ''' */ - /* idx 87 */ {3, 39, NULL}, /* ''' */ - /* idx 88 */ {3, 39, NULL}, /* ''' */ - /* idx 89 */ {3, 39, NULL}, /* ''' */ - /* idx 90 */ {3, 39, NULL}, /* ''' */ - /* idx 91 */ {3, 39, NULL}, /* ''' */ - /* idx 92 */ {3, 39, NULL}, /* ''' */ - /* idx 93 */ {3, 39, NULL}, /* ''' */ - /* idx 94 */ {3, 39, NULL}, /* ''' */ - /* idx 95 */ {3, 39, NULL}, /* ''' */ - /* idx 96 */ {3, 43, NULL}, /* '+' */ - /* idx 97 */ {3, 43, NULL}, /* '+' */ - /* idx 98 */ {3, 43, NULL}, /* '+' */ - /* idx 99 */ {3, 43, NULL}, /* '+' */ - /* idx 100 */ {3, 43, NULL}, /* '+' */ - /* idx 101 */ {3, 43, NULL}, /* '+' */ - /* idx 102 */ {3, 43, NULL}, /* '+' */ - /* idx 103 */ {3, 43, NULL}, /* '+' */ - /* idx 104 */ {3, 43, NULL}, /* '+' */ - /* idx 105 */ {3, 43, NULL}, /* '+' */ - /* idx 106 */ {3, 43, NULL}, /* '+' */ - /* idx 107 */ {3, 43, NULL}, /* '+' */ - /* idx 108 */ {3, 43, NULL}, /* '+' */ - /* idx 109 */ {3, 43, NULL}, /* '+' */ - /* idx 110 */ {3, 43, NULL}, /* '+' */ - /* idx 111 */ {3, 43, NULL}, /* '+' */ - /* idx 112 */ {3, 43, NULL}, /* '+' */ - /* idx 113 */ {3, 43, NULL}, /* '+' */ - /* idx 114 */ {3, 43, NULL}, /* '+' */ - /* idx 115 */ {3, 43, NULL}, /* '+' */ - /* idx 116 */ {3, 43, NULL}, /* '+' */ - /* idx 117 */ {3, 43, NULL}, /* '+' */ - /* idx 118 */ {3, 43, NULL}, /* '+' */ - /* idx 119 */ {3, 43, NULL}, /* '+' */ - /* idx 120 */ {3, 43, NULL}, /* '+' */ - /* idx 121 */ {3, 43, NULL}, /* '+' */ - /* idx 122 */ {3, 43, NULL}, /* '+' */ - /* idx 123 */ {3, 43, NULL}, /* '+' */ - /* idx 124 */ {3, 43, NULL}, /* '+' */ - /* idx 125 */ {3, 43, NULL}, /* '+' */ - /* idx 126 */ {3, 43, NULL}, /* '+' */ - /* idx 127 */ {3, 43, NULL}, /* '+' */ - /* idx 128 */ {3, 124, NULL}, /* '|' */ - /* idx 129 */ {3, 124, NULL}, /* '|' */ - /* idx 130 */ {3, 124, NULL}, /* '|' */ - /* idx 131 */ {3, 124, NULL}, /* '|' */ - /* idx 132 */ {3, 124, NULL}, /* '|' */ - /* idx 133 */ {3, 124, NULL}, /* '|' */ - /* idx 134 */ {3, 124, NULL}, /* '|' */ - /* idx 135 */ {3, 124, NULL}, /* '|' */ - /* idx 136 */ {3, 124, NULL}, /* '|' */ - /* idx 137 */ {3, 124, NULL}, /* '|' */ - /* idx 138 */ {3, 124, NULL}, /* '|' */ - /* idx 139 */ {3, 124, NULL}, /* '|' */ - /* idx 140 */ {3, 124, NULL}, /* '|' */ - /* idx 141 */ {3, 124, NULL}, /* '|' */ - /* idx 142 */ {3, 124, NULL}, /* '|' */ - /* idx 143 */ {3, 124, NULL}, /* '|' */ - /* idx 144 */ {3, 124, NULL}, /* '|' */ - /* idx 145 */ {3, 124, NULL}, /* '|' */ - /* idx 146 */ {3, 124, NULL}, /* '|' */ - /* idx 147 */ {3, 124, NULL}, /* '|' */ - /* idx 148 */ {3, 124, NULL}, /* '|' */ - /* idx 149 */ {3, 124, NULL}, /* '|' */ - /* idx 150 */ {3, 124, NULL}, /* '|' */ - /* idx 151 */ {3, 124, NULL}, /* '|' */ - /* idx 152 */ {3, 124, NULL}, /* '|' */ - /* idx 153 */ {3, 124, NULL}, /* '|' */ - /* idx 154 */ {3, 124, NULL}, /* '|' */ - /* idx 155 */ {3, 124, NULL}, /* '|' */ - /* idx 156 */ {3, 124, NULL}, /* '|' */ - /* idx 157 */ {3, 124, NULL}, /* '|' */ - /* idx 158 */ {3, 124, NULL}, /* '|' */ - /* idx 159 */ {3, 124, NULL}, /* '|' */ - /* idx 160 */ {4, 35, NULL}, /* '#' */ - /* idx 161 */ {4, 35, NULL}, /* '#' */ - /* idx 162 */ {4, 35, NULL}, /* '#' */ - /* idx 163 */ {4, 35, NULL}, /* '#' */ - /* idx 164 */ {4, 35, NULL}, /* '#' */ - /* idx 165 */ {4, 35, NULL}, /* '#' */ - /* idx 166 */ {4, 35, NULL}, /* '#' */ - /* idx 167 */ {4, 35, NULL}, /* '#' */ - /* idx 168 */ {4, 35, NULL}, /* '#' */ - /* idx 169 */ {4, 35, NULL}, /* '#' */ - /* idx 170 */ {4, 35, NULL}, /* '#' */ - /* idx 171 */ {4, 35, NULL}, /* '#' */ - /* idx 172 */ {4, 35, NULL}, /* '#' */ - /* idx 173 */ {4, 35, NULL}, /* '#' */ - /* idx 174 */ {4, 35, NULL}, /* '#' */ - /* idx 175 */ {4, 35, NULL}, /* '#' */ - /* idx 176 */ {4, 62, NULL}, /* '>' */ - /* idx 177 */ {4, 62, NULL}, /* '>' */ - /* idx 178 */ {4, 62, NULL}, /* '>' */ - /* idx 179 */ {4, 62, NULL}, /* '>' */ - /* idx 180 */ {4, 62, NULL}, /* '>' */ - /* idx 181 */ {4, 62, NULL}, /* '>' */ - /* idx 182 */ {4, 62, NULL}, /* '>' */ - /* idx 183 */ {4, 62, NULL}, /* '>' */ - /* idx 184 */ {4, 62, NULL}, /* '>' */ - /* idx 185 */ {4, 62, NULL}, /* '>' */ - /* idx 186 */ {4, 62, NULL}, /* '>' */ - /* idx 187 */ {4, 62, NULL}, /* '>' */ - /* idx 188 */ {4, 62, NULL}, /* '>' */ - /* idx 189 */ {4, 62, NULL}, /* '>' */ - /* idx 190 */ {4, 62, NULL}, /* '>' */ - /* idx 191 */ {4, 62, NULL}, /* '>' */ - /* idx 192 */ {5, 0, NULL}, /* . */ - /* idx 193 */ {5, 0, NULL}, /* . */ - /* idx 194 */ {5, 0, NULL}, /* . */ - /* idx 195 */ {5, 0, NULL}, /* . */ - /* idx 196 */ {5, 0, NULL}, /* . */ - /* idx 197 */ {5, 0, NULL}, /* . */ - /* idx 198 */ {5, 0, NULL}, /* . */ - /* idx 199 */ {5, 0, NULL}, /* . */ - /* idx 200 */ {5, 36, NULL}, /* $ */ - /* idx 201 */ {5, 36, NULL}, /* $ */ - /* idx 202 */ {5, 36, NULL}, /* $ */ - /* idx 203 */ {5, 36, NULL}, /* $ */ - /* idx 204 */ {5, 36, NULL}, /* $ */ - /* idx 205 */ {5, 36, NULL}, /* $ */ - /* idx 206 */ {5, 36, NULL}, /* $ */ - /* idx 207 */ {5, 36, NULL}, /* $ */ - /* idx 208 */ {5, 64, NULL}, /* '@' */ - /* idx 209 */ {5, 64, NULL}, /* '@' */ - /* idx 210 */ {5, 64, NULL}, /* '@' */ - /* idx 211 */ {5, 64, NULL}, /* '@' */ - /* idx 212 */ {5, 64, NULL}, /* '@' */ - /* idx 213 */ {5, 64, NULL}, /* '@' */ - /* idx 214 */ {5, 64, NULL}, /* '@' */ - /* idx 215 */ {5, 64, NULL}, /* '@' */ - /* idx 216 */ {5, 91, NULL}, /* '[' */ - /* idx 217 */ {5, 91, NULL}, /* '[' */ - /* idx 218 */ {5, 91, NULL}, /* '[' */ - /* idx 219 */ {5, 91, NULL}, /* '[' */ - /* idx 220 */ {5, 91, NULL}, /* '[' */ - /* idx 221 */ {5, 91, NULL}, /* '[' */ - /* idx 222 */ {5, 91, NULL}, /* '[' */ - /* idx 223 */ {5, 91, NULL}, /* '[' */ - /* idx 224 */ {5, 93, NULL}, /* ']' */ - /* idx 225 */ {5, 93, NULL}, /* ']' */ - /* idx 226 */ {5, 93, NULL}, /* ']' */ - /* idx 227 */ {5, 93, NULL}, /* ']' */ - /* idx 228 */ {5, 93, NULL}, /* ']' */ - /* idx 229 */ {5, 93, NULL}, /* ']' */ - /* idx 230 */ {5, 93, NULL}, /* ']' */ - /* idx 231 */ {5, 93, NULL}, /* ']' */ - /* idx 232 */ {5, 126, NULL}, /* '~' */ - /* idx 233 */ {5, 126, NULL}, /* '~' */ - /* idx 234 */ {5, 126, NULL}, /* '~' */ - /* idx 235 */ {5, 126, NULL}, /* '~' */ - /* idx 236 */ {5, 126, NULL}, /* '~' */ - /* idx 237 */ {5, 126, NULL}, /* '~' */ - /* idx 238 */ {5, 126, NULL}, /* '~' */ - /* idx 239 */ {5, 126, NULL}, /* '~' */ - /* idx 240 */ {6, 94, NULL}, /* '^' */ - /* idx 241 */ {6, 94, NULL}, /* '^' */ - /* idx 242 */ {6, 94, NULL}, /* '^' */ - /* idx 243 */ {6, 94, NULL}, /* '^' */ - /* idx 244 */ {6, 125, NULL}, /* '}' */ - /* idx 245 */ {6, 125, NULL}, /* '}' */ - /* idx 246 */ {6, 125, NULL}, /* '}' */ - /* idx 247 */ {6, 125, NULL}, /* '}' */ - /* idx 248 */ {7, 60, NULL}, /* '<' */ - /* idx 249 */ {7, 60, NULL}, /* '<' */ - /* idx 250 */ {7, 96, NULL}, /* '`' */ - /* idx 251 */ {7, 96, NULL}, /* '`' */ - /* idx 252 */ {7, 123, NULL}, /* '{' */ - /* idx 253 */ {7, 123, NULL}, /* '{' */ - /* idx 254 */ {8, 0, &byte2_pref0}, /* escape */ - /* idx 255 */ {8, 0, &byte2_pref1} /* escape */ -}; - -static struct stbl byte1_pref1 = { - 8, - byte1_pref1_array -}; - -static struct ssym byte0_array[] = { - /* idx 0 */ {5, 48, NULL}, /* '0' */ - /* idx 1 */ {5, 48, NULL}, /* '0' */ - /* idx 2 */ {5, 48, NULL}, /* '0' */ - /* idx 3 */ {5, 48, NULL}, /* '0' */ - /* idx 4 */ {5, 48, NULL}, /* '0' */ - /* idx 5 */ {5, 48, NULL}, /* '0' */ - /* idx 6 */ {5, 48, NULL}, /* '0' */ - /* idx 7 */ {5, 48, NULL}, /* '0' */ - /* idx 8 */ {5, 49, NULL}, /* '1' */ - /* idx 9 */ {5, 49, NULL}, /* '1' */ - /* idx 10 */ {5, 49, NULL}, /* '1' */ - /* idx 11 */ {5, 49, NULL}, /* '1' */ - /* idx 12 */ {5, 49, NULL}, /* '1' */ - /* idx 13 */ {5, 49, NULL}, /* '1' */ - /* idx 14 */ {5, 49, NULL}, /* '1' */ - /* idx 15 */ {5, 49, NULL}, /* '1' */ - /* idx 16 */ {5, 50, NULL}, /* '2' */ - /* idx 17 */ {5, 50, NULL}, /* '2' */ - /* idx 18 */ {5, 50, NULL}, /* '2' */ - /* idx 19 */ {5, 50, NULL}, /* '2' */ - /* idx 20 */ {5, 50, NULL}, /* '2' */ - /* idx 21 */ {5, 50, NULL}, /* '2' */ - /* idx 22 */ {5, 50, NULL}, /* '2' */ - /* idx 23 */ {5, 50, NULL}, /* '2' */ - /* idx 24 */ {5, 97, NULL}, /* 'a' */ - /* idx 25 */ {5, 97, NULL}, /* 'a' */ - /* idx 26 */ {5, 97, NULL}, /* 'a' */ - /* idx 27 */ {5, 97, NULL}, /* 'a' */ - /* idx 28 */ {5, 97, NULL}, /* 'a' */ - /* idx 29 */ {5, 97, NULL}, /* 'a' */ - /* idx 30 */ {5, 97, NULL}, /* 'a' */ - /* idx 31 */ {5, 97, NULL}, /* 'a' */ - /* idx 32 */ {5, 99, NULL}, /* 'c' */ - /* idx 33 */ {5, 99, NULL}, /* 'c' */ - /* idx 34 */ {5, 99, NULL}, /* 'c' */ - /* idx 35 */ {5, 99, NULL}, /* 'c' */ - /* idx 36 */ {5, 99, NULL}, /* 'c' */ - /* idx 37 */ {5, 99, NULL}, /* 'c' */ - /* idx 38 */ {5, 99, NULL}, /* 'c' */ - /* idx 39 */ {5, 99, NULL}, /* 'c' */ - /* idx 40 */ {5, 101, NULL}, /* 'e' */ - /* idx 41 */ {5, 101, NULL}, /* 'e' */ - /* idx 42 */ {5, 101, NULL}, /* 'e' */ - /* idx 43 */ {5, 101, NULL}, /* 'e' */ - /* idx 44 */ {5, 101, NULL}, /* 'e' */ - /* idx 45 */ {5, 101, NULL}, /* 'e' */ - /* idx 46 */ {5, 101, NULL}, /* 'e' */ - /* idx 47 */ {5, 101, NULL}, /* 'e' */ - /* idx 48 */ {5, 105, NULL}, /* 'i' */ - /* idx 49 */ {5, 105, NULL}, /* 'i' */ - /* idx 50 */ {5, 105, NULL}, /* 'i' */ - /* idx 51 */ {5, 105, NULL}, /* 'i' */ - /* idx 52 */ {5, 105, NULL}, /* 'i' */ - /* idx 53 */ {5, 105, NULL}, /* 'i' */ - /* idx 54 */ {5, 105, NULL}, /* 'i' */ - /* idx 55 */ {5, 105, NULL}, /* 'i' */ - /* idx 56 */ {5, 111, NULL}, /* 'o' */ - /* idx 57 */ {5, 111, NULL}, /* 'o' */ - /* idx 58 */ {5, 111, NULL}, /* 'o' */ - /* idx 59 */ {5, 111, NULL}, /* 'o' */ - /* idx 60 */ {5, 111, NULL}, /* 'o' */ - /* idx 61 */ {5, 111, NULL}, /* 'o' */ - /* idx 62 */ {5, 111, NULL}, /* 'o' */ - /* idx 63 */ {5, 111, NULL}, /* 'o' */ - /* idx 64 */ {5, 115, NULL}, /* 's' */ - /* idx 65 */ {5, 115, NULL}, /* 's' */ - /* idx 66 */ {5, 115, NULL}, /* 's' */ - /* idx 67 */ {5, 115, NULL}, /* 's' */ - /* idx 68 */ {5, 115, NULL}, /* 's' */ - /* idx 69 */ {5, 115, NULL}, /* 's' */ - /* idx 70 */ {5, 115, NULL}, /* 's' */ - /* idx 71 */ {5, 115, NULL}, /* 's' */ - /* idx 72 */ {5, 116, NULL}, /* 't' */ - /* idx 73 */ {5, 116, NULL}, /* 't' */ - /* idx 74 */ {5, 116, NULL}, /* 't' */ - /* idx 75 */ {5, 116, NULL}, /* 't' */ - /* idx 76 */ {5, 116, NULL}, /* 't' */ - /* idx 77 */ {5, 116, NULL}, /* 't' */ - /* idx 78 */ {5, 116, NULL}, /* 't' */ - /* idx 79 */ {5, 116, NULL}, /* 't' */ - /* idx 80 */ {6, 32, NULL}, /* ' ' */ - /* idx 81 */ {6, 32, NULL}, /* ' ' */ - /* idx 82 */ {6, 32, NULL}, /* ' ' */ - /* idx 83 */ {6, 32, NULL}, /* ' ' */ - /* idx 84 */ {6, 37, NULL}, /* '%' */ - /* idx 85 */ {6, 37, NULL}, /* '%' */ - /* idx 86 */ {6, 37, NULL}, /* '%' */ - /* idx 87 */ {6, 37, NULL}, /* '%' */ - /* idx 88 */ {6, 45, NULL}, /* '-' */ - /* idx 89 */ {6, 45, NULL}, /* '-' */ - /* idx 90 */ {6, 45, NULL}, /* '-' */ - /* idx 91 */ {6, 45, NULL}, /* '-' */ - /* idx 92 */ {6, 46, NULL}, /* '.' */ - /* idx 93 */ {6, 46, NULL}, /* '.' */ - /* idx 94 */ {6, 46, NULL}, /* '.' */ - /* idx 95 */ {6, 46, NULL}, /* '.' */ - /* idx 96 */ {6, 47, NULL}, /* '/' */ - /* idx 97 */ {6, 47, NULL}, /* '/' */ - /* idx 98 */ {6, 47, NULL}, /* '/' */ - /* idx 99 */ {6, 47, NULL}, /* '/' */ - /* idx 100 */ {6, 51, NULL}, /* '3' */ - /* idx 101 */ {6, 51, NULL}, /* '3' */ - /* idx 102 */ {6, 51, NULL}, /* '3' */ - /* idx 103 */ {6, 51, NULL}, /* '3' */ - /* idx 104 */ {6, 52, NULL}, /* '4' */ - /* idx 105 */ {6, 52, NULL}, /* '4' */ - /* idx 106 */ {6, 52, NULL}, /* '4' */ - /* idx 107 */ {6, 52, NULL}, /* '4' */ - /* idx 108 */ {6, 53, NULL}, /* '5' */ - /* idx 109 */ {6, 53, NULL}, /* '5' */ - /* idx 110 */ {6, 53, NULL}, /* '5' */ - /* idx 111 */ {6, 53, NULL}, /* '5' */ - /* idx 112 */ {6, 54, NULL}, /* '6' */ - /* idx 113 */ {6, 54, NULL}, /* '6' */ - /* idx 114 */ {6, 54, NULL}, /* '6' */ - /* idx 115 */ {6, 54, NULL}, /* '6' */ - /* idx 116 */ {6, 55, NULL}, /* '7' */ - /* idx 117 */ {6, 55, NULL}, /* '7' */ - /* idx 118 */ {6, 55, NULL}, /* '7' */ - /* idx 119 */ {6, 55, NULL}, /* '7' */ - /* idx 120 */ {6, 56, NULL}, /* '8' */ - /* idx 121 */ {6, 56, NULL}, /* '8' */ - /* idx 122 */ {6, 56, NULL}, /* '8' */ - /* idx 123 */ {6, 56, NULL}, /* '8' */ - /* idx 124 */ {6, 57, NULL}, /* '9' */ - /* idx 125 */ {6, 57, NULL}, /* '9' */ - /* idx 126 */ {6, 57, NULL}, /* '9' */ - /* idx 127 */ {6, 57, NULL}, /* '9' */ - /* idx 128 */ {6, 61, NULL}, /* '=' */ - /* idx 129 */ {6, 61, NULL}, /* '=' */ - /* idx 130 */ {6, 61, NULL}, /* '=' */ - /* idx 131 */ {6, 61, NULL}, /* '=' */ - /* idx 132 */ {6, 65, NULL}, /* 'A' */ - /* idx 133 */ {6, 65, NULL}, /* 'A' */ - /* idx 134 */ {6, 65, NULL}, /* 'A' */ - /* idx 135 */ {6, 65, NULL}, /* 'A' */ - /* idx 136 */ {6, 95, NULL}, /* '_' */ - /* idx 137 */ {6, 95, NULL}, /* '_' */ - /* idx 138 */ {6, 95, NULL}, /* '_' */ - /* idx 139 */ {6, 95, NULL}, /* '_' */ - /* idx 140 */ {6, 98, NULL}, /* 'b' */ - /* idx 141 */ {6, 98, NULL}, /* 'b' */ - /* idx 142 */ {6, 98, NULL}, /* 'b' */ - /* idx 143 */ {6, 98, NULL}, /* 'b' */ - /* idx 144 */ {6, 100, NULL}, /* 'd' */ - /* idx 145 */ {6, 100, NULL}, /* 'd' */ - /* idx 146 */ {6, 100, NULL}, /* 'd' */ - /* idx 147 */ {6, 100, NULL}, /* 'd' */ - /* idx 148 */ {6, 102, NULL}, /* 'f' */ - /* idx 149 */ {6, 102, NULL}, /* 'f' */ - /* idx 150 */ {6, 102, NULL}, /* 'f' */ - /* idx 151 */ {6, 102, NULL}, /* 'f' */ - /* idx 152 */ {6, 103, NULL}, /* 'g' */ - /* idx 153 */ {6, 103, NULL}, /* 'g' */ - /* idx 154 */ {6, 103, NULL}, /* 'g' */ - /* idx 155 */ {6, 103, NULL}, /* 'g' */ - /* idx 156 */ {6, 104, NULL}, /* 'h' */ - /* idx 157 */ {6, 104, NULL}, /* 'h' */ - /* idx 158 */ {6, 104, NULL}, /* 'h' */ - /* idx 159 */ {6, 104, NULL}, /* 'h' */ - /* idx 160 */ {6, 108, NULL}, /* 'l' */ - /* idx 161 */ {6, 108, NULL}, /* 'l' */ - /* idx 162 */ {6, 108, NULL}, /* 'l' */ - /* idx 163 */ {6, 108, NULL}, /* 'l' */ - /* idx 164 */ {6, 109, NULL}, /* 'm' */ - /* idx 165 */ {6, 109, NULL}, /* 'm' */ - /* idx 166 */ {6, 109, NULL}, /* 'm' */ - /* idx 167 */ {6, 109, NULL}, /* 'm' */ - /* idx 168 */ {6, 110, NULL}, /* 'n' */ - /* idx 169 */ {6, 110, NULL}, /* 'n' */ - /* idx 170 */ {6, 110, NULL}, /* 'n' */ - /* idx 171 */ {6, 110, NULL}, /* 'n' */ - /* idx 172 */ {6, 112, NULL}, /* 'p' */ - /* idx 173 */ {6, 112, NULL}, /* 'p' */ - /* idx 174 */ {6, 112, NULL}, /* 'p' */ - /* idx 175 */ {6, 112, NULL}, /* 'p' */ - /* idx 176 */ {6, 114, NULL}, /* 'r' */ - /* idx 177 */ {6, 114, NULL}, /* 'r' */ - /* idx 178 */ {6, 114, NULL}, /* 'r' */ - /* idx 179 */ {6, 114, NULL}, /* 'r' */ - /* idx 180 */ {6, 117, NULL}, /* 'u' */ - /* idx 181 */ {6, 117, NULL}, /* 'u' */ - /* idx 182 */ {6, 117, NULL}, /* 'u' */ - /* idx 183 */ {6, 117, NULL}, /* 'u' */ - /* idx 184 */ {7, 58, NULL}, /* ':' */ - /* idx 185 */ {7, 58, NULL}, /* ':' */ - /* idx 186 */ {7, 66, NULL}, /* 'B' */ - /* idx 187 */ {7, 66, NULL}, /* 'B' */ - /* idx 188 */ {7, 67, NULL}, /* 'C' */ - /* idx 189 */ {7, 67, NULL}, /* 'C' */ - /* idx 190 */ {7, 68, NULL}, /* 'D' */ - /* idx 191 */ {7, 68, NULL}, /* 'D' */ - /* idx 192 */ {7, 69, NULL}, /* 'E' */ - /* idx 193 */ {7, 69, NULL}, /* 'E' */ - /* idx 194 */ {7, 70, NULL}, /* 'F' */ - /* idx 195 */ {7, 70, NULL}, /* 'F' */ - /* idx 196 */ {7, 71, NULL}, /* 'G' */ - /* idx 197 */ {7, 71, NULL}, /* 'G' */ - /* idx 198 */ {7, 72, NULL}, /* 'H' */ - /* idx 199 */ {7, 72, NULL}, /* 'H' */ - /* idx 200 */ {7, 73, NULL}, /* 'I' */ - /* idx 201 */ {7, 73, NULL}, /* 'I' */ - /* idx 202 */ {7, 74, NULL}, /* 'J' */ - /* idx 203 */ {7, 74, NULL}, /* 'J' */ - /* idx 204 */ {7, 75, NULL}, /* 'K' */ - /* idx 205 */ {7, 75, NULL}, /* 'K' */ - /* idx 206 */ {7, 76, NULL}, /* 'L' */ - /* idx 207 */ {7, 76, NULL}, /* 'L' */ - /* idx 208 */ {7, 77, NULL}, /* 'M' */ - /* idx 209 */ {7, 77, NULL}, /* 'M' */ - /* idx 210 */ {7, 78, NULL}, /* 'N' */ - /* idx 211 */ {7, 78, NULL}, /* 'N' */ - /* idx 212 */ {7, 79, NULL}, /* 'O' */ - /* idx 213 */ {7, 79, NULL}, /* 'O' */ - /* idx 214 */ {7, 80, NULL}, /* 'P' */ - /* idx 215 */ {7, 80, NULL}, /* 'P' */ - /* idx 216 */ {7, 81, NULL}, /* 'Q' */ - /* idx 217 */ {7, 81, NULL}, /* 'Q' */ - /* idx 218 */ {7, 82, NULL}, /* 'R' */ - /* idx 219 */ {7, 82, NULL}, /* 'R' */ - /* idx 220 */ {7, 83, NULL}, /* 'S' */ - /* idx 221 */ {7, 83, NULL}, /* 'S' */ - /* idx 222 */ {7, 84, NULL}, /* 'T' */ - /* idx 223 */ {7, 84, NULL}, /* 'T' */ - /* idx 224 */ {7, 85, NULL}, /* 'U' */ - /* idx 225 */ {7, 85, NULL}, /* 'U' */ - /* idx 226 */ {7, 86, NULL}, /* 'V' */ - /* idx 227 */ {7, 86, NULL}, /* 'V' */ - /* idx 228 */ {7, 87, NULL}, /* 'W' */ - /* idx 229 */ {7, 87, NULL}, /* 'W' */ - /* idx 230 */ {7, 89, NULL}, /* 'Y' */ - /* idx 231 */ {7, 89, NULL}, /* 'Y' */ - /* idx 232 */ {7, 106, NULL}, /* 'j' */ - /* idx 233 */ {7, 106, NULL}, /* 'j' */ - /* idx 234 */ {7, 107, NULL}, /* 'k' */ - /* idx 235 */ {7, 107, NULL}, /* 'k' */ - /* idx 236 */ {7, 113, NULL}, /* 'q' */ - /* idx 237 */ {7, 113, NULL}, /* 'q' */ - /* idx 238 */ {7, 118, NULL}, /* 'v' */ - /* idx 239 */ {7, 118, NULL}, /* 'v' */ - /* idx 240 */ {7, 119, NULL}, /* 'w' */ - /* idx 241 */ {7, 119, NULL}, /* 'w' */ - /* idx 242 */ {7, 120, NULL}, /* 'x' */ - /* idx 243 */ {7, 120, NULL}, /* 'x' */ - /* idx 244 */ {7, 121, NULL}, /* 'y' */ - /* idx 245 */ {7, 121, NULL}, /* 'y' */ - /* idx 246 */ {7, 122, NULL}, /* 'z' */ - /* idx 247 */ {7, 122, NULL}, /* 'z' */ - /* idx 248 */ {8, 38, NULL}, /* '&' */ - /* idx 249 */ {8, 42, NULL}, /* '*' */ - /* idx 250 */ {8, 44, NULL}, /* ',' */ - /* idx 251 */ {8, 59, NULL}, /* ';' */ - /* idx 252 */ {8, 88, NULL}, /* 'X' */ - /* idx 253 */ {8, 90, NULL}, /* 'Z' */ - /* idx 254 */ {8, 0, &byte1_pref0}, /* escape */ - /* idx 255 */ {8, 0, &byte1_pref1} /* escape */ -}; - -static struct stbl byte0 = { - 8, - byte0_array -}; diff --git a/bin/varnishtest/vtc_h2_hpack.c b/bin/varnishtest/vtc_h2_hpack.c index 52c8ee9cc..e52f16855 100644 --- a/bin/varnishtest/vtc_h2_hpack.c +++ b/bin/varnishtest/vtc_h2_hpack.c @@ -61,7 +61,7 @@ huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen) int l = 0; uint64_t pack = 0; unsigned pl = 0; /* pack length*/ - struct stbl *tbl = &byte0; + struct stbl *tbl = &tbl_0; struct ssym *sym; (void)nm; @@ -71,7 +71,7 @@ huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen) if (ilen == 0) { if (pl == 0 || (MASK(pack, pl) == (unsigned)((1U << pl) - 1U))) { - assert(tbl == &byte0); + assert(tbl == &tbl_0); return (l); } } @@ -102,7 +102,7 @@ huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen) continue; } str[l++] = sym->chr; - tbl = &byte0; + tbl = &tbl_0; } return (l); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:21 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:21 +0000 (UTC) Subject: [6.0] 5e77f1542 Forgot one build dependency Message-ID: <20180816085321.B8FDA9C3DD@lists.varnish-cache.org> commit 5e77f1542013f0ac2bd477d6628ff808fac4838c Author: Guillaume Quintard Date: Sun Aug 5 19:06:19 2018 -0700 Forgot one build dependency diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 200f43394..fdb640df0 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -85,6 +85,7 @@ teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences awk -f $(srcdir)/gensequences $(srcdir)/sequences \ > $(builddir)/teken_state.h +vtc_h2_hpack.c: vtc_h2_dectbl.h vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h $(srcdir)/huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ mv $@_ $@ From dridi.boukelmoune at gmail.com Thu Aug 16 08:52:49 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:52:49 +0000 (UTC) Subject: [6.0] 833703773 fix regression from 1bb0688c9a744e3f89fe0624f58c1ba0d4347867 Message-ID: <20180816085249.DF5699B3F5@lists.varnish-cache.org> commit 8337037737c6265cbae19eb94608d6d2c7ce8b34 Author: Nils Goroll Date: Thu Apr 26 08:41:39 2018 +0200 fix regression from 1bb0688c9a744e3f89fe0624f58c1ba0d4347867 thanks to coverity diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index 1d6877ea3..77315f5b5 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -808,7 +808,7 @@ shard_param_task(VRT_CTX, const void *id, if (task->priv) { p = task->priv; CHECK_OBJ_NOTNULL(p, VMOD_SHARD_SHARD_PARAM_MAGIC); - assert(p->scope = SCOPE_TASK); + assert(p->scope == SCOPE_TASK); /* XXX VSL(SLT_Debug, 0, "shard_param_task(id %p, pa %p) = %p (found, ws=%p)", From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:16 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:16 +0000 (UTC) Subject: [6.0] 213146253 For backends with PROXYv1, send UNKNOWN in a probe if the backend's address family is neither of AF_INET or AF_INET6. Message-ID: <20180816085316.D11E09C116@lists.varnish-cache.org> commit 2131462532dfe8fbe60e71280f12d695e8a4d3c8 Author: Geoff Simmons Date: Mon Jul 2 00:13:12 2018 +0200 For backends with PROXYv1, send UNKNOWN in a probe if the backend's address family is neither of AF_INET or AF_INET6. This means that UNKNOWN is sent in probes to UDS backends when .proxy_header=1 is set. Also verify that a UDS backend receives PROXY LOCAL in a probe when .proxy_header=2 is set. Fixes #2702 Closes #2726 diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 0ae04956c..08bddf833 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -265,8 +265,9 @@ vbp_write_proxy_v1(struct vbp_target *vt, int *sock) else if (ss.ss_family == AF_INET) VSB_printf(&vsb, " TCP4 "); else - WRONG("Unknown family"); - VSB_printf(&vsb, "%s %s %s %s\r\n", addr, addr, port, port); + VSB_printf(&vsb, " UNKNOWN\r\n"); + if (ss.ss_family == AF_INET6 || ss.ss_family == AF_INET) + VSB_printf(&vsb, "%s %s %s %s\r\n", addr, addr, port, port); AZ(VSB_finish(&vsb)); return (vbp_write(vt, sock, VSB_data(&vsb), VSB_len(&vsb))); diff --git a/bin/varnishtest/tests/r02702.vtc b/bin/varnishtest/tests/r02702.vtc new file mode 100644 index 000000000..6208f0c07 --- /dev/null +++ b/bin/varnishtest/tests/r02702.vtc @@ -0,0 +1,74 @@ +varnishtest "probes to UDS backends with .proxy_header in [12]" + +# Since we can only reliably forward IP addresses via PROXY with +# Varnish, we can't use the trick from o00002.vtc (use a Varnish +# instance listening for PROXY as a backend) to verify PROXYv1 (but +# the PROXY header can be viewed in the test log). + +# We just verify that the probe is good (and that Varnish doesn't +# crash with WRONG). + +server s1 -listen "${tmpdir}/s1.sock" { + rxreq + txresp +} -start + +# For PROXYv1 with a UDS backend, we send PROXY UNKNOWN in the probe. +varnish v1 -vcl { + backend s1 { + .path = "${s1_sock}"; + .proxy_header = 1; + + .probe = { + .window = 1; + .threshold = 1; + .interval = 0.5s; + } + } +} -start + +delay 1 + +varnish v1 -cliexpect "vcl1.s1[ ]+probe[ ]+1/1[ ]+good" backend.list + +# For PROXYv2, we apply a trick similar to o0000[24].vtc, since +# Varnish accepts (and ignores) PROXY LOCAL. + +server s2 { + rxreq + expect req.http.Host == "v2" + expect req.http.X-Forwarded-For == "0.0.0.0" + txresp +} -start + +varnish v2 -arg "-a ${tmpdir}/v2.sock,PROXY" -vcl { + backend s2 { .host = "${s2_addr}"; .port = "${s2_port}"; } +} -start + +varnish v3 -vcl { + backend bp { + .path = "${v2_addr}"; + .host_header = "v2"; + .proxy_header = 2; + + .probe = { + .window = 1; + .threshold = 1; + .interval = 0.5s; + } + } +} -start + +server s1 -wait + +delay 1 + +varnish v3 -cliexpect "vcl1.bp[ ]+probe[ ]+1/1[ ]+good" backend.list + +# Verify in the v2 log that PROXY LOCAL was sent. + +logexpect l1 -v v2 -d 1 -g session -q "Proxy" { + expect 0 * Begin sess + expect * = Proxy {^\d+ local local local local$} + expect * = End +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] f80c03d68 Reintroduce the req.grace variable, change keep behavior Message-ID: <20180816085317.094E59C127@lists.varnish-cache.org> commit f80c03d682720be5d4e59d5ca53c829028671270 Author: P?l Hermunn Johansen Date: Tue Jun 12 16:33:07 2018 +0200 Reintroduce the req.grace variable, change keep behavior The req.grace variable can be set in vcl_recv to cap the grace of objects in the cache, in the same way as in 3.0.x The "keep" behavior changes with this patch. We now always go to vcl_miss when the expired object is out of grace, or we go to the waiting list. The result is that it is no longer possible to deliver a "keep" object in vcl_hit. Note that when we get to vcl_miss, we will still have the 304 candidate, but without the detour by vcl_hit. This commit changes VCL, but only slightly, so we aim to back port this to earlier versions of Varnish Cache. Refs: #1799 and #2519 diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 2298feaad..adf9e34a9 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -470,6 +470,7 @@ struct req { uint8_t digest[DIGEST_LEN]; double d_ttl; + double d_grace; ssize_t req_bodybytes; /* Parsed req bodybytes */ const struct stevedore *storage; diff --git a/bin/varnishd/cache/cache_expire.c b/bin/varnishd/cache/cache_expire.c index efe3814c6..6aa1ae07c 100644 --- a/bin/varnishd/cache/cache_expire.c +++ b/bin/varnishd/cache/cache_expire.c @@ -74,6 +74,24 @@ EXP_Ttl(const struct req *req, const struct objcore *oc) return (oc->t_origin + r); } +/*-------------------------------------------------------------------- + * Calculate an object's effective ttl+grace time, taking req.grace into + * account if it is available. + */ + +double +EXP_Ttl_grace(const struct req *req, const struct objcore *oc) +{ + double g; + + CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); + + g = oc->grace; + if (req != NULL && req->d_grace >= 0. && req->d_grace < g) + g = req->d_grace; + return (EXP_Ttl(req, oc) + g); +} + /*-------------------------------------------------------------------- * Post an objcore to the exp_thread's inbox. */ diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 55a451cf7..38531b149 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -478,36 +478,50 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp, busy_found = 0; } + if (exp_oc != NULL && EXP_Ttl_grace(req, exp_oc) < req->t_req) { + /* the newest object is out of grace */ + if (!busy_found) { + /* + * here we get to insert the busy object. This + * translates to a MISS with a 304 candidate. + */ + assert(oh->refcnt > 1); + assert(exp_oc->objhead == oh); + exp_oc->refcnt++; + /* Insert objcore in objecthead and release mutex */ + *bocp = hsh_insert_busyobj(wrk, oh); + /* NB: no deref of objhead, new object inherits reference */ + Lck_Unlock(&oh->mtx); + *ocp = exp_oc; + return (HSH_MISS); + } else { + /* we have no use for this very expired object */ + exp_oc = NULL; + } + } if (exp_oc != NULL) { + /* + * here the object is within grace, so we expect it to + * be delivered + */ assert(oh->refcnt > 1); assert(exp_oc->objhead == oh); + exp_oc->refcnt++; if (!busy_found) { *bocp = hsh_insert_busyobj(wrk, oh); retval = HSH_EXPBUSY; } else { AZ(req->hash_ignore_busy); - /* - * here we have a busy object, but if the stale object - * is not under grace we go to the waiting list - * instead of returning the stale object - */ - if (EXP_Ttl(req, exp_oc) + exp_oc->grace < req->t_req) - retval = HSH_BUSY; - else - retval = HSH_EXP; - } - if (retval != HSH_BUSY) { - exp_oc->refcnt++; - - if (exp_oc->hits < LONG_MAX) - exp_oc->hits++; - Lck_Unlock(&oh->mtx); - if (retval == HSH_EXP) - assert(HSH_DerefObjHead(wrk, &oh)); - *ocp = exp_oc; - return (retval); + retval = HSH_EXP; } + if (exp_oc->hits < LONG_MAX) + exp_oc->hits++; + Lck_Unlock(&oh->mtx); + if (retval == HSH_EXP) + assert(HSH_DerefObjHead(wrk, &oh)); + *ocp = exp_oc; + return (retval); } if (!busy_found) { diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index b55a0c007..83ddc4760 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -508,14 +508,23 @@ cnt_lookup(struct worker *wrk, struct req *req) AZ(req->objcore); if (lr == HSH_MISS) { - /* Found nothing */ - AZ(oc); - if (busy != NULL) { + /* Found nothing or an object that was out of grace */ + if (oc == NULL) { + /* Nothing */ + if (busy != NULL) { + AN(busy->flags & OC_F_BUSY); + req->objcore = busy; + req->req_step = R_STP_MISS; + } else { + req->req_step = R_STP_PASS; + } + } else { + /* Object out of grace */ + AN(busy); /* Else we should be on waiting list */ AN(busy->flags & OC_F_BUSY); req->objcore = busy; + req->stale_oc = oc; req->req_step = R_STP_MISS; - } else { - req->req_step = R_STP_PASS; } return (REQ_FSM_MORE); } @@ -805,6 +814,7 @@ cnt_recv_prep(struct req *req, const char *ci) AN(req->director_hint); req->d_ttl = -1; + req->d_grace = -1; req->disable_esi = 0; req->hash_always_miss = 0; req->hash_ignore_busy = 0; diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index af122f768..e967f1d7f 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -127,6 +127,7 @@ void VDI_Init(void); /* cache_exp.c */ double EXP_Ttl(const struct req *, const struct objcore *); +double EXP_Ttl_grace(const struct req *, const struct objcore *oc); void EXP_Insert(struct worker *wrk, struct objcore *oc); void EXP_Remove(struct objcore *); diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index c06dde561..c902bee4c 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -435,7 +435,7 @@ VRT_r_obj_storage(VRT_CTX) /*--------------------------------------------------------------------*/ -#define REQ_VAR_L(nm, elem, type,extra) \ +#define REQ_VAR_L(nm, elem, type, extra) \ \ VCL_VOID \ VRT_l_req_##nm(VRT_CTX, type arg) \ @@ -460,6 +460,8 @@ REQ_VAR_L(backend_hint, director_hint, VCL_BACKEND,) REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND) REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;) REQ_VAR_R(ttl, d_ttl, VCL_DURATION) +REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;) +REQ_VAR_R(grace, d_grace, VCL_DURATION) /*--------------------------------------------------------------------*/ diff --git a/bin/varnishtest/tests/b00098.vtc b/bin/varnishtest/tests/b00062.vtc similarity index 100% rename from bin/varnishtest/tests/b00098.vtc rename to bin/varnishtest/tests/b00062.vtc diff --git a/bin/varnishtest/tests/b00064.vtc b/bin/varnishtest/tests/b00064.vtc new file mode 100644 index 000000000..6054ec1e6 --- /dev/null +++ b/bin/varnishtest/tests/b00064.vtc @@ -0,0 +1,126 @@ +varnishtest "Test that req.grace will hold a client when a miss is anticipated" + +barrier b1 cond 2 + +server s1 { + rxreq + expect req.url == "/" + txresp -body "0" + + rxreq + expect req.url == "/" + txresp -body "1" + + # second time we get a request, we use some time to serve it + rxreq + expect req.url == "/" + barrier b1 sync + delay .1 + txresp -body "2" + + # Last request, to a different URL to catch it if varnish asks for "/" too many times + rxreq + expect req.url == "/2" + txresp -body "x" +} -start + +varnish v1 -vcl+backend { + import std; + + sub vcl_recv { + # When we know in vcl_recv that we will have no grace, it is now + # possible to signal this to the lookup function: + if (req.http.X-no-grace) { + set req.grace = 0s; + } + } + sub vcl_hit { + set req.http.X-grace = obj.grace; + } + sub vcl_backend_response { + set beresp.ttl = 0.1s; + set beresp.grace = 1m; + } + sub vcl_deliver { + if (req.http.X-grace) { + set resp.http.X-grace = req.http.X-grace; + set resp.http.X-req-grace = req.grace; + } + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 200 + expect resp.body == "0" + expect resp.http.X-grace == + # let the object's ttl expire + delay .2 + # get a genuinely fresh object by disabling grace + # we will not get to vcl_hit to see the grace + txreq -hdr "X-no-grace: true" + rxresp + expect resp.status == 200 + expect resp.body == "1" + expect resp.http.X-grace == + expect resp.http.X-req-grace == +} -run + +# let the latest object's ttl expire. +delay .2 + +varnish v1 -expect n_object == 1 + +# c2 asks for the object under grace +client c2 { + txreq + rxresp + # we did not disable grace in the request, so we should get the graced object here + expect resp.status == 200 + expect resp.body == "1" + expect resp.http.X-grace == "60.000" + expect resp.http.X-req-grace < 0. +} -start + +delay .1 + +# c3 asks for graced object, but now we disable grace. +client c3 { + txreq -hdr "X-no-grace: true" + rxresp + expect resp.status == 200 + # Here we have disable grace and should get the object from the background fetch, + # which will take us into vcl_hit + expect resp.body == "2" + expect resp.http.X-grace == "60.000" + expect resp.http.X-req-grace == "0.000" +} -start + +delay .1 + +# c4 does not disable grace, and should get the grace object even +# though c3 is waiting on the background thread to deliver a new +# version. + +client c4 { + txreq + rxresp + barrier b1 sync + expect resp.status == 200 + # We should get what c1 got in the very beginning + expect resp.body == "1" + expect resp.http.X-grace == "60.000" + expect resp.http.X-req-grace < 0. +} -start + +client c2 -wait +client c3 -wait +client c4 -wait + +client c5 { + txreq -url "/2" + rxresp + expect resp.status == 200 + expect resp.body == "x" +} -run diff --git a/bin/varnishtest/tests/r02705.vtc b/bin/varnishtest/tests/r02705.vtc new file mode 100644 index 000000000..54bec95c2 --- /dev/null +++ b/bin/varnishtest/tests/r02705.vtc @@ -0,0 +1,51 @@ +varnishtest "No vcl_hit when grace has run out, with working IMS" + +server s1 { + rxreq + txresp -hdr {Etag: "Foo"} -body "1" + + rxreq + txresp -status 304 + + rxreq + expect req.url == "/2" + txresp -body "3" +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_response { + set beresp.ttl = 1ms; + set beresp.grace = 0s; + set beresp.keep = 1m; + if (bereq.http.Hit) { + set beresp.http.Hit = bereq.http.Hit; + } + } + sub vcl_hit { + set req.http.Hit = "HIT"; + } +} -start + +client c1 { + txreq + rxresp + expect resp.http.Hit == + expect resp.http.Etag == {"Foo"} + expect resp.status == 200 + expect resp.body == "1" + delay .2 + txreq + rxresp + expect resp.http.Hit == + expect resp.http.Etag == {"Foo"} + expect resp.status == 200 + expect resp.body == "1" +} -run + +client c2 { + txreq -url "/2" + rxresp + expect resp.http.Hit == + expect resp.body == "3" +} -run + diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 30fee32d7..b08b947fb 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -304,6 +304,21 @@ req.ttl Deprecated and scheduled for removal with varnish release 7. +req.grace + + Type: DURATION + + Readable from: client + + Writable from: client + + + Upper limit on the object grace. + + During lookup the minimum of req.grace and the object's stored + grace value will be used as the object's grace. + + req.xid Type: STRING From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] 4faaa055f Undeprecate req.ttl Message-ID: <20180816085317.2CD5F9C19F@lists.varnish-cache.org> commit 4faaa055fc01632065db87041d3cac71a0db2163 Author: P?l Hermunn Johansen Date: Thu Jun 7 14:21:04 2018 +0200 Undeprecate req.ttl Right now there are use cases that cannot be solved without req.ttl, so we undeprecate it. diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index b08b947fb..2bb40b214 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -296,13 +296,6 @@ req.ttl Upper limit on the object age for cache lookups to return hit. - Usage of req.ttl should be replaced with a check on - obj.ttl in vcl_hit, returning miss when needed, but - this currently hits bug #1799, so an additional - workaround is required. - - Deprecated and scheduled for removal with varnish release 7. - req.grace From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] ab7b2b184 Update the documentation on grace and keep Message-ID: <20180816085317.5305B9C1B0@lists.varnish-cache.org> commit ab7b2b184c7dcc5ffea4b8ec812de95ec2ead874 Author: P?l Hermunn Johansen Date: Thu Jun 7 14:56:24 2018 +0200 Update the documentation on grace and keep The main point is to clearly recomend using req.grace for the most common use case - using different grace time when the backend is healthy. diff --git a/doc/sphinx/users-guide/vcl-grace.rst b/doc/sphinx/users-guide/vcl-grace.rst index 8db2a4649..dddfac5f7 100644 --- a/doc/sphinx/users-guide/vcl-grace.rst +++ b/doc/sphinx/users-guide/vcl-grace.rst @@ -34,15 +34,11 @@ Keep ~~~~ Setting an object's `keep` tells Varnish that it should keep an object -in the cache for some additional time. There are two reasons to do this: - -* To use the object to construct a conditional GET backend request (with - If-Modified-Since: and/or ?f-None-Match: headers), allowing the backend - to reply with a 304 Not Modified response, which may be more efficient - on the backend and saves re-transmitting the unchanged body. -* To be able to serve the object when grace has expired but we have a - problem with getting a fresh object from the backend. This will require - a change in ``sub vcl_hit``, as described below. +in the cache for some additional time. The reasons to set `keep` is to +use the object to construct a conditional GET backend request (with +If-Modified-Since: and/or ?f-None-Match: headers), allowing the +backend to reply with a 304 Not Modified response, which may be more +efficient on the backend and saves re-transmitting the unchanged body. The values are additive, so if grace is 10 seconds and keep is 1 minute, then objects will survive in cache for 70 seconds after the TTL has @@ -64,9 +60,9 @@ The effect of grace and keep For most users setting the default grace and/or a suitable grace for each object is enough. The default VCL will do the right thing and -behave as described above. However, if you want to customize how varnish -behaves by changing ``sub vcl_hit``, then you should know some of the -details on how this works. +behave as described above. However, if you want to customize how +varnish behaves, then you should know some of the details on how this +works. When ``sub vcl_recv`` ends with ``return (lookup)`` (which is the default behavior), Varnish will look for a matching object in its @@ -78,13 +74,15 @@ will consider the following: Then, Varnish reacts using the following rules: -* If there is no backend request for the object, one is scheduled and - ``sub vcl_hit`` is called immediately. -* If there is a backend request going on, but the object is under grace, - ``sub vcl_hit`` is called immediately. -* If there is a backend request going on, but the grace has expired, - processing is halted until the backend request has finished and a - fresh object is available. +* If the `grace period` has run out and there is no ongoing backend + request, then ``sub vcl_miss`` is called immediately, and the object + will be used as a 304 candidate. +* If the `grace period` has run out and there is an ongoing backend + request, then the request will wait until the backend request + finishes. +* If there is no backend request for the object, one is scheduled. +* Assuming the object will be delivered, ``sub vcl_hit`` is called + immediately. Note that the backend fetch happens asynchronously, and the moment the new object is in it will replace the one we've already got. @@ -106,9 +104,17 @@ used. It looks like this:: return (miss); } -If you follow the code, you see that Varnish delivers graced objects -while fetching fresh copies, but if grace has expired the clients have to -wait until a new copy is available. +The effect of the built-in VCL is in fact equivalent to the following:: + + sub vcl_hit { + return (deliver); + } + +This is because ``obj.ttl + obj.grace > 0s`` always will evaluate to +true. However, the the VCL is as it is to show users how to +differentiate between a pure hit and a `grace` hit. With the next +major version of Varnish, the default VCL is planned to change to the +latter, shorter version. Misbehaving servers ~~~~~~~~~~~~~~~~~~~ @@ -118,104 +124,42 @@ web- and application servers. If you have enabled :ref:`users-guide-advanced_backend_servers-health` you can check if the backend is sick and modify the behavior when it -comes to grace. There are essentially two ways of doing this. You can -explicitly deliver kept object (that is not within grace) when you see -that the backend is sick, or you can explicitly `not` serve an expired -object when you know that the backend is healthy. The two methods have -slightly different characteristics, as we shall see. - -In both cases we assume that you avoid inserting objects into the cache -when you get certain errors from the backend, for example by using the -following:: - - sub vcl_backend_response { - if (beresp.status == 503 && bereq.is_bgfetch) { - return (abandon); - } - } - -Method 1: When the backend is healthy, use a lower grace value -============================================================== - -Imagine that you have set an object's grace to a high value that you -wish to use when the backend is sick, for example:: +comes to grace. This can done in the following way:: sub vcl_backend_response { set beresp.grace = 24h; - // no keep + // no keep - the grace should be enough for 304 candidates } -Then you can use the following code as your ``sub vcl_hit``:: - - if (std.healthy(req.backend_hint)) { - // change the behavior for health backends: Cap grace to 10s - if (obj.ttl + obj.grace > 0s && obj.ttl + 10s > 0s) { - return (deliver); - } else { - return (miss); - } - } - -The effect of this is that, when the backend is healthy, objects with -grace above 10 seconds will have an `effective` grace of 10 seconds. -When the backend is sick, the default VCL kicks in, and the long grace -is used. - -This method has one potentially serious problem when more than one -client asks for an object that has expired its TTL. If the second of -these requests arrives after the effective grace, but before the first -request has completed, then the second request will be turned into a -`pass`. - -In practice this method works well in most cases, but if you -experience excessive `pass` behavior, this translates to a reduced -hit rate and higher load on the backend. When this happens you will -see the error message `vcl_hit{} returns miss without busy object` in -the log. - -Method 2: When the backend is sick, deliver kept objects -======================================================== - -With this method, we assume that we have used `sub backend_response` -to set `beresp.grace` to a value that is suitable for healthy backends, -and with a `beresp.keep` that corresponds to the time we want to serve -the object when the backend is sick. For example:: - - sub vcl_backend_response { - set beresp.grace = 10s; - set beresp.keep = 24h; + sub vcl_recv { + if (std.healthy(req.backend_hint)) { + // change the behavior for healthy backends: Cap grace to 10s + set req.grace = 10s; + } } -The appropriate code for ``vcl_hit`` then becomes:: - - if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace + obj.keep > 0s)) { - return (deliver); - } +In the example above, the special variable ``req.grace`` is set. The +effect is that, when the backend is healthy, objects with grace above +10 seconds will have an `effective` grace of 10 seconds. When the +backend is sick, the default VCL kicks in, and the long grace is used. -Typically you can omit the second part of the if test due to the -expiry thread deleting objects where `grace + keep` has expired. It is -possible that the `expiry thread` can be lagging slightly behind, but -for almost all practical purposes you are probably fine with the -following:: +Additionally, you might want to stop cache insertion when a backend fetch +returns an ``5xx`` error:: - if (!std.healthy(req.backend_hint)) { - return (deliver); - } - -The problem with this solution concerns requests that are waiting for -a backend fetch to finish. If the backend fetch gets to ``return -(abandon)``, then all the requests that are waiting will get to ``sub -vcl_hit`` with an `error object` created by the error handling -code/VCL. In other words, you risk that some clients will get errors -instead of the more desirable stale objects. + sub vcl_backend_response { + if (beresp.status >= 500 && bereq.is_bgfetch) { + return (abandon); + } + } Summary ~~~~~~~ -Grace mode allows Varnish to deliver slightly stale content to clients while -getting a fresh version from the backend. The result is faster load times -with a low cost. +Grace mode allows Varnish to deliver slightly stale content to clients +while getting a fresh version from the backend. The result is faster +load times at lower cost. -It is possible to change the behavior when it comes to grace and keep, for -example by changing the `effective` grace depending on the health of the -backend, but you have to be careful. +It is possible to limit the grace during lookup by setting +``req.grace`` and then change the behavior when it comes to +grace. Often this is done to change the `effective` grace depending on +the health of the backend. From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] 67b453350 Test case that shows return(abandon) to avoid cache insertion Message-ID: <20180816085317.78D009C1DA@lists.varnish-cache.org> commit 67b453350520d9f7d62350a5fbc180dabaefd02e Author: P?l Hermunn Johansen Date: Fri Jun 15 10:54:48 2018 +0200 Test case that shows return(abandon) to avoid cache insertion diff --git a/bin/varnishtest/tests/b00063.vtc b/bin/varnishtest/tests/b00063.vtc new file mode 100644 index 000000000..1adfe2680 --- /dev/null +++ b/bin/varnishtest/tests/b00063.vtc @@ -0,0 +1,90 @@ +varnishtest "Abandon background fetch when backend serves 5xx" + +barrier b1 cond 2 +barrier b2 cond 3 + +server s1 { + # This is what we want to get to all client requests below + rxreq + expect req.url == "/1" + txresp -body "1" + + # 503s will be abandoned when we have a bgfetch + rxreq + expect req.url == "/1" + txresp -status 503 -body "2" + + # varnish will disconnect on a 503 + accept + rxreq + expect req.url == "/1" + # wait until varnish has delivered 200 before replying + # with the 404 + barrier b2 sync + delay .1 + # this response will not be abandoned + txresp -status 404 -reason "Not Found" -body "3" + + # some other resource at the end + rxreq + expect req.url == "/2" + txresp -body "4" +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_response { + if (beresp.status >= 500 && bereq.is_bgfetch) { + return (abandon); + } + if (beresp.status >= 400) { + set beresp.ttl = 1m; + } else { + set beresp.ttl = 1ms; + } + set beresp.grace = 1m; + } +} -start + +client c1 { + txreq -url "/1" + rxresp + expect resp.status == 200 + expect resp.body == "1" + delay .2 + txreq -url "/1" + rxresp + expect resp.status == 200 + expect resp.body == "1" + delay .2 + barrier b1 sync + txreq -url "/1" + rxresp + expect resp.status == 200 + expect resp.body == "1" + barrier b2 sync +} -start + +client c2 { + barrier b1 sync + txreq -url "/1" + rxresp + expect resp.status == 200 + expect resp.body == "1" + barrier b2 sync +} -start + +client c1 -wait +client c2 -wait + +client c3 { + delay .1 + # We should now get a HIT on the 404: + txreq -url "/1" + rxresp + expect resp.status == 404 + expect resp.body == "3" + # do a different resource to make sure we got the right number of reqs to /1 + txreq -url "/2" + rxresp + expect resp.body == "4" +} -run From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:17 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:17 +0000 (UTC) Subject: [6.0] cb370c88d simplify cnt_lookup Message-ID: <20180816085317.A38D99C1EF@lists.varnish-cache.org> commit cb370c88d284ac4cb7ee8375e0f36a50a8472199 Author: Nils Goroll Date: Tue Jun 19 15:43:25 2018 +0200 simplify cnt_lookup diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 83ddc4760..17c9899c7 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -508,23 +508,16 @@ cnt_lookup(struct worker *wrk, struct req *req) AZ(req->objcore); if (lr == HSH_MISS) { - /* Found nothing or an object that was out of grace */ - if (oc == NULL) { - /* Nothing */ - if (busy != NULL) { - AN(busy->flags & OC_F_BUSY); - req->objcore = busy; - req->req_step = R_STP_MISS; - } else { - req->req_step = R_STP_PASS; - } - } else { - /* Object out of grace */ - AN(busy); /* Else we should be on waiting list */ + if (busy != NULL) { + /* hitmiss, out-of-grace or ordinary miss */ AN(busy->flags & OC_F_BUSY); req->objcore = busy; req->stale_oc = oc; req->req_step = R_STP_MISS; + } else { + /* hitpass */ + AZ(oc); + req->req_step = R_STP_PASS; } return (REQ_FSM_MORE); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:20 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:20 +0000 (UTC) Subject: [6.0] b57e5296d Accommodate musl libc that has a smaller stack Message-ID: <20180816085320.CEF9A9C38C@lists.varnish-cache.org> commit b57e5296d712f5da74f69d0d8d1442bef40f7129 Author: Guillaume Quintard Date: Tue Jul 17 13:09:29 2018 -0700 Accommodate musl libc that has a smaller stack diff --git a/bin/varnishd/waiter/cache_waiter_epoll.c b/bin/varnishd/waiter/cache_waiter_epoll.c index 9e2e2a31e..c48b72396 100644 --- a/bin/varnishd/waiter/cache_waiter_epoll.c +++ b/bin/varnishd/waiter/cache_waiter_epoll.c @@ -33,6 +33,8 @@ //lint -e{766} #include "config.h" +#include + #if defined(HAVE_EPOLL_CTL) #include @@ -69,7 +71,7 @@ struct vwe { static void * vwe_thread(void *priv) { - struct epoll_event ev[NEEV], *ep; + struct epoll_event *ev, *ep; struct waited *wp; struct waiter *w; double now, then; @@ -82,6 +84,8 @@ vwe_thread(void *priv) CHECK_OBJ_NOTNULL(w, WAITER_MAGIC); THR_SetName("cache-epoll"); THR_Init(); + ev = malloc(sizeof(struct epoll_event) * NEEV); + AN(ev); now = VTIM_real(); while (1) { @@ -146,6 +150,7 @@ vwe_thread(void *priv) if (vwe->nwaited == 0 && vwe->die) break; } + free(ev); closefd(&vwe->pipe[0]); closefd(&vwe->pipe[1]); closefd(&vwe->epfd); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:21 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:21 +0000 (UTC) Subject: [6.0] e4f82eed1 Fix build Message-ID: <20180816085322.142C49C3F3@lists.varnish-cache.org> commit e4f82eed1333ad9075927c9023cbac2ac8a51f8a Author: Poul-Henning Kamp Date: Mon Aug 6 06:29:05 2018 +0000 Fix build diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index fdb640df0..b34caa435 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -87,7 +87,8 @@ teken_state.h: $(srcdir)/sequences $(srcdir)/gensequences vtc_h2_hpack.c: vtc_h2_dectbl.h vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h - $(srcdir)/huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ + $(PYTHON) $(srcdir)/huffman_gen.py \ + $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ mv $@_ $@ CLEANFILES = $(builddir)/teken_state.h From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:22 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:22 +0000 (UTC) Subject: [6.0] 182cd072f Coverity spotted this as a resource-leak, even though it amounts to counting deck-chairs on the Titanic. Message-ID: <20180816085322.5F9EE9C407@lists.varnish-cache.org> commit 182cd072ffe5ece36be22dd6a5e94c8631772dcc Author: Poul-Henning Kamp Date: Mon Aug 6 06:40:33 2018 +0000 Coverity spotted this as a resource-leak, even though it amounts to counting deck-chairs on the Titanic. diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index b9ad25a8e..dacb32260 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -1224,6 +1224,7 @@ vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt, "'%s' must be followed by BOOL," " found %s.\n", tokstr, vcc_utype(e2->fmt)); vcc_ErrWhere2(tl, tk, tl->t); + vcc_delete_expr(e2); return; } bprintf(buf, "\v1\v-\n%s\v+\n\v2", tokstr); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:22 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:22 +0000 (UTC) Subject: [6.0] 2b4adddee Unbotch my refactoring of || and && handling in VCL expressions. Message-ID: <20180816085322.8A40B9C416@lists.varnish-cache.org> commit 2b4adddeea32a4a7a2066ab2edd613a09cc6406e Author: Poul-Henning Kamp Date: Mon Aug 6 16:00:20 2018 +0000 Unbotch my refactoring of || and && handling in VCL expressions. Fixes: #2729 diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index dacb32260..39a01af38 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -1215,7 +1215,7 @@ vcc_expr_bin_bool(struct vcc *tl, struct expr **e, vcc_type_t fmt, while (tl->t->tok == ourtok) { vcc_NextToken(tl); tk = tl->t; - vcc_expr_not(tl, &e2, fmt); + up(tl, &e2, fmt); ERRCHK(tl); vcc_expr_tobool(tl, &e2); ERRCHK(tl); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:22 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:22 +0000 (UTC) Subject: [6.0] 41b2ac6bf Add regression test for #2729, but don't spend an entire test-case on it Message-ID: <20180816085322.BD39D9C41D@lists.varnish-cache.org> commit 41b2ac6bf13b4367488399d278aa8d9b5c2c3e93 Author: Poul-Henning Kamp Date: Mon Aug 6 17:24:04 2018 +0000 Add regression test for #2729, but don't spend an entire test-case on it diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index 60e1fb346..da563157f 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -137,6 +137,11 @@ varnish v1 -vcl { elseif (3) { } else if (4) { } else { } + + # regression test for #2729 + if (req.grace < 0s || req.grace < 1s && req.grace < 2s) { + return (pass); + } } } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:22 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:22 +0000 (UTC) Subject: [6.0] bbccfcd69 Make the output tab-space compliant Message-ID: <20180816085322.EBDEE9C435@lists.varnish-cache.org> commit bbccfcd69b600e7453618b6544f158d84fc79254 Author: Poul-Henning Kamp Date: Mon Aug 6 17:27:52 2018 +0000 Make the output tab-space compliant diff --git a/bin/varnishtest/huffman_gen.py b/bin/varnishtest/huffman_gen.py index 1486bd41d..00ff16fe6 100755 --- a/bin/varnishtest/huffman_gen.py +++ b/bin/varnishtest/huffman_gen.py @@ -85,7 +85,7 @@ for pfx in sorted(tbls.keys(), reverse=True): for s in tbl: for j in range(2 ** (msl - s.vall)): print(" {} {{{}, {:3d}, {}}},".format( - " "*13 if j else "/* idx {:3d} */".format(s.val + j), + "\t " if j else "/* idx {:3d} */".format(s.val + j), s.vall, s.chr % 256, s.esc if s.esc else "NULL")) print('''}}; From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] 8be0403af Add std.fnmatch() Message-ID: <20180816085323.1C9069C442@lists.varnish-cache.org> commit 8be0403af3bd3786c832df2d26f84eb87f480b2c Author: Geoff Simmons Date: Fri Jul 27 17:26:16 2018 +0200 Add std.fnmatch() Closes: #2737 diff --git a/bin/varnishtest/tests/m00050.vtc b/bin/varnishtest/tests/m00050.vtc new file mode 100644 index 000000000..a6578a6bd --- /dev/null +++ b/bin/varnishtest/tests/m00050.vtc @@ -0,0 +1,188 @@ +varnishtest "std.fnmatch()" + +varnish v1 -vcl { + import std; + backend b { .host = "${bad_ip}"; } + + sub vcl_recv { + return (synth(200)); + } + + sub vcl_synth { + set resp.http.Match + = std.fnmatch(req.http.Pattern, req.http.Subject); + set resp.http.Match-Nopathname = std.fnmatch(req.http.Pattern, + req.http.Subject, + pathname=false); + set resp.http.Match-Noescape = std.fnmatch(req.http.Pattern, + req.http.Subject, + noescape=true); + set resp.http.Match-Period = std.fnmatch(req.http.Pattern, + req.http.Subject, + period=true); + } +} -start + +client c1 { + txreq -hdr "Pattern: /foo/" -hdr "Subject: /foo/" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/" -hdr "Subject: /bar/" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/*" -hdr "Subject: /foo/bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/bar/*" -hdr "Subject: /foo/bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/?" -hdr "Subject: /foo/b" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/?" -hdr "Subject: /foo/bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[a-z]" -hdr "Subject: /foo/b" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[a-z]" -hdr "Subject: /foo/B" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[!a-z]" -hdr "Subject: /foo/B" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/*/quux" -hdr "Subject: /foo/bar/baz/quux" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == "true" + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/?/bar" -hdr "Subject: /foo///bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == "true" + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: /foo/[a/b]/bar" -hdr "Subject: /foo///bar" + rxresp + expect resp.status == 200 + expect resp.http.Match == "false" + expect resp.http.Match-Nopathname == "true" + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr {Pattern: \\foo} -hdr {Subject: \foo} + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == "false" + expect resp.http.Match-Period == resp.http.Match + + txreq -hdr "Pattern: *foo" -hdr "Subject: .foo" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == "false" + + txreq -hdr "Pattern: /*foo" -hdr "Subject: /.foo" + rxresp + expect resp.status == 200 + expect resp.http.Match == "true" + expect resp.http.Match-Nopathname == resp.http.Match + expect resp.http.Match-Noescape == resp.http.Match + expect resp.http.Match-Period == "false" +} -run + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + import std; + + sub vcl_deliver { + set resp.http.Match + = std.fnmatch(req.http.Pattern, req.http.Subject); + } +} + +client c1 { + txreq -hdr "Pattern: /foo/" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" { + expect 0 * Begin + expect * = VCL_Error {^std\.fnmatch\(\): subject is NULL$} + expect * = End +} -run + +logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" { + expect 0 * Begin + expect * = VCL_Error {^std\.fnmatch\(\): pattern is NULL$} + expect * = End +} -start + +client c1 { + txreq -hdr "Subject: /foo/" + rxresp + expect resp.status == 503 + expect resp.reason == "VCL failed" +} -run + +logexpect l1 -wait diff --git a/configure.ac b/configure.ac index bda22723e..d56dadf62 100644 --- a/configure.ac +++ b/configure.ac @@ -208,6 +208,7 @@ AC_CHECK_HEADERS([sys/vfs.h]) AC_CHECK_HEADERS([endian.h]) AC_CHECK_HEADERS([pthread_np.h], [], [], [#include ]) AC_CHECK_HEADERS([priv.h]) +AC_CHECK_HEADERS([fnmatch.h], [], [AC_MSG_ERROR([fnmatch.h is required])]) # Checks for library functions. _VARNISH_CHECK_EXPLICIT_BZERO @@ -218,6 +219,7 @@ AC_CHECK_FUNCS([closefrom]) AC_CHECK_FUNCS([sigaltstack]) AC_CHECK_FUNCS([getpeereid]) AC_CHECK_FUNCS([getpeerucred]) +AC_CHECK_FUNCS([fnmatch], [], [AC_MSG_ERROR([fnmatch(3) is required])]) save_LIBS="${LIBS}" LIBS="${PTHREAD_LIBS}" diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index c8305ae9d..c46d24156 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -361,8 +361,70 @@ $Function BOOL syntax(REAL) Description Returns the true if VCL version is at least REAL. +$Function BOOL fnmatch(STRING pattern, STRING subject, BOOL pathname=1, + BOOL noescape=0, BOOL period=0) + +Description + Shell-style pattern matching; returns `true` if *subject* + matches *pattern*, where *pattern* may contain wildcard + characters such as \* or ?. + + The match is executed by the implementation of `fnmatch(3)` on + your system. The rules for pattern matching on most systems + include the following: + + * \* matches any sequence of characters + + * ? matches a single character + + * a bracket expresion such as [abc] or [!0-9] is interpreted + as a character class according to the rules of basic regular + expressions (*not* PCRE regexen), except that ! is used for + character class negation instead of ^. + + If *pathname* is `true`, then the forward slash character / is + only matched literally, and never matches \*, ? or a bracket + expression. Otherwise, / may match one of those patterns. By + default, *pathname* is `true`. + + If *noescape* is `true`, then the backslash character \\ is + matched as an ordinary character. Otherwise, \\ is an escape + character, and matches the character that follows it in the + `pattern`. For example, \\\\ matches \\ when *noescape* is + `true`, and \\\\ when `false`. By default, *noescape* is + `false`. + + If *period* is `true`, then a leading period character . only + matches literally, and never matches \*, ? or a bracket + expression. A period is leading if it is the first character + in `subject`; if *pathname* is also `true`, then a period that + immediately follows a / is also leading (as in "/."). By + default, *period* is `false`. + + `fnmatch()` invokes VCL failure and returns `false` if either + of *pattern* or *subject* is NULL -- for example, if an unset + header is specified. + +Examples + | # Matches URLs such as /foo/bar and /foo/bar/baz + | if (std.fnmatch("/foo/\*", req.url)) { ... } + | + | # Matches /foo/bar/quux, but not /foo/bar/baz/quux + | if (std.fnmatch("/foo/\*/quux", req.url)) { ... } + | + | # Matches /foo/bar/quux and /foo/bar/baz/quux + | if (std.fnmatch("/foo/\*/quux", req.url, pathname=false)) { ... } + | + | # Matches /foo/bar, /foo/car and /foo/far + | if (std.fnmatch("/foo/?ar", req.url)) { ... } + | + | # Matches /foo/ followed by a non-digit + | if (std.fnmatch("/foo/[!0-9]", req.url)) { ... } + + SEE ALSO ======== * :ref:`varnishd(1)` * :ref:`vsl(7)` +* `fnmatch(3)` diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c index 865199372..5d7aa3b8d 100644 --- a/lib/libvmod_std/vmod_std.c +++ b/lib/libvmod_std/vmod_std.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "cache/cache.h" @@ -304,3 +305,28 @@ vmod_syntax(VRT_CTX, VCL_REAL r) */ return (round(r * 10) <= ctx->syntax); } + +VCL_BOOL v_matchproto_(td_std_fnmatch) +vmod_fnmatch(VRT_CTX, VCL_STRING pattern, VCL_STRING subject, + VCL_BOOL pathname, VCL_BOOL noescape, VCL_BOOL period) +{ + int flags = 0; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (pattern == NULL) { + VRT_fail(ctx, "std.fnmatch(): pattern is NULL"); + return (0); + } + if (subject == NULL) { + VRT_fail(ctx, "std.fnmatch(): subject is NULL"); + return (0); + } + + if (pathname) + flags |= FNM_PATHNAME; + if (noescape) + flags |= FNM_NOESCAPE; + if (period) + flags |= FNM_PERIOD; + return (fnmatch(pattern, subject, flags) != FNM_NOMATCH); +} From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] 3662f0115 Expand macros in HAproxy config files. Message-ID: <20180816085323.413B59C469@lists.varnish-cache.org> commit 3662f0115e45e84c006e83823380047f97fe42a4 Author: Poul-Henning Kamp Date: Tue Aug 7 09:38:04 2018 +0000 Expand macros in HAproxy config files. Submitted by: Frederic Lecaille diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index 2de165031..a3e89c713 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -435,7 +435,7 @@ haproxy_check_conf(struct haproxy *h, const char *expect) static void haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) { - struct vsb *vsb, *vsb2; + struct vsb *vsb, *vsb2, *vsb3; vsb = VSB_new_auto(); AN(vsb); @@ -454,14 +454,18 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) AZ(haproxy_build_backends(h, VSB_data(vsb))); + vsb3 = macro_expand(h->vl, VSB_data(vsb)); + AN(vsb3); + if (VFIL_writefile(h->workdir, h->cfg_fn, - VSB_data(vsb), VSB_len(vsb)) != 0) + VSB_data(vsb3), VSB_len(vsb3)) != 0) vtc_fatal(h->vl, "failed to write haproxy configuration file: %s (%d)", strerror(errno), errno); - vtc_dump(h->vl, 4, "conf", VSB_data(vsb), VSB_len(vsb)); + vtc_dump(h->vl, 4, "conf", VSB_data(vsb3), VSB_len(vsb3)); + VSB_destroy(&vsb3); VSB_destroy(&vsb2); VSB_destroy(&vsb); } From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] e8e6a2db4 Typo Message-ID: <20180816085323.623DC9C474@lists.varnish-cache.org> commit e8e6a2db4487722eed9a313012d1ba132267b2a1 Author: Geoff Simmons Date: Tue Aug 7 12:46:46 2018 +0200 Typo diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index c46d24156..87bcca003 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -377,7 +377,7 @@ Description * ? matches a single character - * a bracket expresion such as [abc] or [!0-9] is interpreted + * a bracket expression such as [abc] or [!0-9] is interpreted as a character class according to the rules of basic regular expressions (*not* PCRE regexen), except that ! is used for character class negation instead of ^. From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] 3207306db Example fix. Message-ID: <20180816085323.8493E9C487@lists.varnish-cache.org> commit 3207306db060e40898f32e4da34aa797a49a666d Author: Geoff Simmons Date: Tue Aug 7 14:14:35 2018 +0200 Example fix. diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc index 87bcca003..c30172ed1 100644 --- a/lib/libvmod_std/vmod.vcc +++ b/lib/libvmod_std/vmod.vcc @@ -406,9 +406,12 @@ Description header is specified. Examples - | # Matches URLs such as /foo/bar and /foo/bar/baz + | # Matches URLs such as /foo/bar and /foo/baz | if (std.fnmatch("/foo/\*", req.url)) { ... } | + | # Matches URLs such as /foo/bar/baz and /foo/baz/quux + | if (std.fnmatch("/foo/\*/\*", bereq.url)) { ... } + | | # Matches /foo/bar/quux, but not /foo/bar/baz/quux | if (std.fnmatch("/foo/\*/quux", req.url)) { ... } | From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] f4166da9a Report STRANDS as STRING in documentation. Message-ID: <20180816085323.A609C9C49C@lists.varnish-cache.org> commit f4166da9ae264133cde9eb1d79590d07136ff70c Author: Poul-Henning Kamp Date: Mon Aug 13 06:55:01 2018 +0000 Report STRANDS as STRING in documentation. Start pylinting while here anyway. diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index 8937aefac..669450fb7 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -86,14 +86,14 @@ CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h \\ ''' -privs = { +PRIVS = { 'PRIV_CALL': "struct vmod_priv *", 'PRIV_VCL': "struct vmod_priv *", 'PRIV_TASK': "struct vmod_priv *", 'PRIV_TOP': "struct vmod_priv *", } -ctypes = { +CTYPES = { 'ACL': "VCL_ACL", 'BACKEND': "VCL_BACKEND", 'BLOB': "VCL_BLOB", @@ -116,7 +116,7 @@ ctypes = { 'VOID': "VCL_VOID", } -ctypes.update(privs) +CTYPES.update(PRIVS) ####################################################################### @@ -162,7 +162,7 @@ def lwrap(s, width=64): ll.append(p + s[:y + 1]) s = s[y + 1:].lstrip() p = " " - if len(s) > 0: + if s: ll.append(p + s) return "\n".join(ll) + "\n" @@ -182,19 +182,19 @@ def fmt_cstruct(fo, mn, x): inputline = None -def err(str, warn=True): +def err(txt, warn=True): if inputline is not None: print("While parsing line:\n\t", inputline) if opts.strict or not warn: - print("ERROR: " + str, file=sys.stderr) + print("ERROR: " + txt, file=sys.stderr) exit(1) else: - print("WARNING: " + str, file=sys.stderr) + print("WARNING: " + txt, file=sys.stderr) ####################################################################### -class ctype(object): +class CType(object): def __init__(self, wl, enums): self.nm = None self.defval = None @@ -202,10 +202,10 @@ class ctype(object): self.opt = False self.vt = wl.pop(0) - self.ct = ctypes.get(self.vt) + self.ct = CTYPES.get(self.vt) if self.ct is None: err("Expected type got '%s'" % self.vt, warn=False) - if len(wl) > 0 and wl[0] == "{": + if wl and wl[0] == "{": if self.vt != "ENUM": err("Only ENUMs take {...} specs", warn=False) self.add_spec(wl, enums) @@ -230,7 +230,7 @@ class ctype(object): x = x[1:-1] elif x[0] == "'" and x[-1] == "'": x = x[1:-1] - assert len(x) > 0 + assert x self.spec.append(x) enums[x] = True w = wl.pop(0) @@ -239,14 +239,14 @@ class ctype(object): assert w == "," def vcl(self): - if self.vt == "STRING_LIST": + if self.vt in ("STRING_LIST", "STRAND"): return "STRING" if self.spec is None: return self.vt return self.vt + " {" + ", ".join(self.spec) + "}" def synopsis(self): - if self.vt == "STRING_LIST": + if self.vt in ("STRING_LIST", "STRAND"): return "STRING" return self.vt @@ -258,7 +258,7 @@ class ctype(object): ####################################################################### -class arg(ctype): +class arg(CType): def __init__(self, wl, argnames, enums, end): super(arg, self).__init__(wl, enums) @@ -299,6 +299,7 @@ class arg(ctype): def lex(l): wl = [] s = 0 + assert l for i in range(len(l)): c = l[i] @@ -342,7 +343,7 @@ def lex(l): ####################################################################### -class prototype(object): +class ProtoType(object): def __init__(self, st, retval=True, prefix=""): self.st = st self.obj = None @@ -351,9 +352,9 @@ class prototype(object): wl = lex(st.line[1]) if retval: - self.retval = ctype(wl, st.vcc.enums) + self.retval = CType(wl, st.vcc.enums) else: - self.retval = ctype(['VOID'], st.vcc.enums) + self.retval = CType(['VOID'], st.vcc.enums) self.bname = wl.pop(0) if not re.match("^[a-zA-Z.][a-zA-Z0-9_]*$", self.bname): @@ -376,12 +377,12 @@ class prototype(object): names = {} n = 0 - while len(wl) > 0: + while wl: n += 1 x = wl.pop(0) if x != ',': err("Expected ',' found '%s'" % x, warn=False) - if len(wl) == 0: + if not wl: break if wl[0] == '[': wl.pop(0) @@ -420,7 +421,7 @@ class prototype(object): t = i.synopsis() else: t = i.vcl() - if t in privs: + if t in PRIVS: continue if i.nm is not None: t += " " + i.nm @@ -528,9 +529,9 @@ class prototype(object): class stanza(object): def __init__(self, l0, doc, vcc): self.line = l0 - while len(doc) > 0 and doc[0] == '': + while doc and doc[0] == '': doc.pop(0) - while len(doc) > 0 and doc[-1] == '': + while doc and doc[-1] == '': doc.pop(-1) self.doc = doc self.vcc = vcc @@ -668,7 +669,7 @@ class s_event(stanza): self.vcc.contents.append(self) def rstfile(self, fo, man): - if len(self.doc) != 0: + if self.doc: err("Not emitting .RST for $Event %s\n" % self.event_func) @@ -684,14 +685,14 @@ class s_event(stanza): def json(self, jl): jl.append([ - "$EVENT", - "Vmod_%s_Func._event" % self.vcc.modname + "$EVENT", + "Vmod_%s_Func._event" % self.vcc.modname ]) class s_function(stanza): def parse(self): - self.proto = prototype(self) + self.proto = ProtoType(self) self.rstlbl = "func_" + self.proto.name self.vcc.contents.append(self) @@ -711,7 +712,7 @@ class s_function(stanza): class s_object(stanza): def parse(self): - self.proto = prototype(self, retval=False) + self.proto = ProtoType(self, retval=False) self.proto.obj = "x" + self.proto.name self.init = copy.copy(self.proto) @@ -799,7 +800,7 @@ class s_method(stanza): p = self.vcc.contents[-1] assert type(p) == s_object self.pfx = p.proto.name - self.proto = prototype(self, prefix=self.pfx) + self.proto = ProtoType(self, prefix=self.pfx) if not self.proto.bname.startswith("."): err("$Method %s: Method names need to start with . (dot)" % self.proto.bname, warn=False) @@ -820,7 +821,7 @@ class s_method(stanza): ####################################################################### -dispatch = { +DISPATCH = { "Module": s_module, "Prefix": s_prefix, "ABI": s_abi, @@ -844,6 +845,7 @@ class vcc(object): self.enums = {} self.strict_abi = True self.auto_synopsis = True + self.modname = None def openfile(self, fn): self.commit_files.append(fn) @@ -858,11 +860,11 @@ class vcc(object): a = "\n" + open(self.inputfile, "r").read() s = a.split("\n$") self.copyright = s.pop(0).strip() - while len(s): + while s: ss = re.split('\n([^\t ])', s.pop(0), maxsplit=1) c = ss[0].split() d = "".join(ss[1:]) - m = dispatch.get(c[0]) + m = DISPATCH.get(c[0]) if m is None: err("Unknown stanze $%s" % ss[:i]) m([c[0], " ".join(c[1:])], d.split('\n'), self) @@ -891,7 +893,7 @@ class vcc(object): for i in self.contents: i.rstfile(fo, man) - if len(self.copyright): + if self.copyright: self.rst_copyright(fo) fo.close() @@ -1075,7 +1077,7 @@ if __name__ == "__main__": help='Output file prefix (default: "vcc_if")') oparser.add_option('-w', '--rstdir', metavar="directory", default='.', help='Where to save the generated RST files ' + - '(default: ".")') + '(default: ".")') oparser.add_option('', '--runtests', action='store_true', default=False, dest="runtests", help=optparse.SUPPRESS_HELP) (opts, args) = oparser.parse_args() From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] c37bed3f9 Respect the end of input buffer when skipping the second [CR]LF after the headers. Message-ID: <20180816085323.CB8AE9C4B0@lists.varnish-cache.org> commit c37bed3f9363be4d2240ebd62beb94558e4d99c4 Author: Poul-Henning Kamp Date: Mon Aug 13 07:10:40 2018 +0000 Respect the end of input buffer when skipping the second [CR]LF after the headers. Fixes: #2731 diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c index ac1a2a86e..dd81863d3 100644 --- a/bin/varnishd/http1/cache_http1_proto.c +++ b/bin/varnishd/http1/cache_http1_proto.c @@ -206,8 +206,11 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc, return (400); } } - if (p < htc->rxbuf_e) - p += vct_skipcrlf(p); + /* We cannot use vct_skipcrlf() we have to respect rxbuf_e */ + if (p+2 <= htc->rxbuf_e && p[0] == '\r' && p[1] == '\n') + p += 2; + else if (p+1 <= htc->rxbuf_e && p[0] == '\n') + p += 1; HTC_RxPipeline(htc, p); htc->rxbuf_e = p; return (0); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:23 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:23 +0000 (UTC) Subject: [6.0] 4d3d349f8 Make the client list all mgt CLI commands Message-ID: <20180816085323.F36879C4C0@lists.varnish-cache.org> commit 4d3d349f8bbd55b7bcd23cffa9abc256f0d33392 Author: Poul-Henning Kamp Date: Mon Aug 13 08:51:41 2018 +0000 Make the client list all mgt CLI commands Fixes: #2682 diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c index 35dac06a6..b38387d67 100644 --- a/bin/varnishd/cache/cache_cli.c +++ b/bin/varnishd/cache/cache_cli.c @@ -100,7 +100,7 @@ CLI_Run(void) cli = VCLS_AddFd(cache_cls, heritage.cli_in, heritage.cli_out, NULL, NULL); AN(cli); - cli->auth = 1; // Non-zero to disable paranoia in vcli_serve + cli->auth = 255; // Non-zero to disable paranoia in vcli_serve do { i = VCLS_Poll(cache_cls, cli, -1); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:24 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:24 +0000 (UTC) Subject: [6.0] 28b48b3c8 In curses mode, always filter in the counters necessary for the header lines. Message-ID: <20180816085324.26C999C4D7@lists.varnish-cache.org> commit 28b48b3c8c08e38da145da50be4aaacd535b9d4a Author: Poul-Henning Kamp Date: Mon Aug 13 09:14:52 2018 +0000 In curses mode, always filter in the counters necessary for the header lines. Fixes: #2678 diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c index 0a78a4513..74a8f5adf 100644 --- a/bin/varnishstat/varnishstat.c +++ b/bin/varnishstat/varnishstat.c @@ -264,6 +264,7 @@ main(int argc, char * const *argv) int once = 0, xml = 0, json = 0, f_list = 0, curses = 0; signed char opt; int i; + int has_f = 0; struct vsc *vsc; vut = VUT_InitProg(argc, argv, &vopt_spec); @@ -293,6 +294,7 @@ main(int argc, char * const *argv) break; case 'f': AN(VSC_Arg(vsc, opt, optarg)); + has_f = 1; break; case 'V': AN(VUT_Arg(vut, opt, optarg)); @@ -315,8 +317,15 @@ main(int argc, char * const *argv) if (VSM_Attach(vd, STDERR_FILENO)) VUT_Error(vut, 1, "%s", VSM_Error(vd)); - if (curses) + if (curses) { + if (has_f) { + AZ(VSC_Arg(vsc, 'f', "MGT.uptime")); + AZ(VSC_Arg(vsc, 'f', "MAIN.uptime")); + AZ(VSC_Arg(vsc, 'f', "MAIN.cache_hit")); + AZ(VSC_Arg(vsc, 'f', "MAIN.cache_miss")); + } do_curses(vd, vsc, 1.0); + } else if (xml) do_xml(vd, vsc); else if (json) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:24 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:24 +0000 (UTC) Subject: [6.0] 8a564bb55 Fix a buffer overflow situation in h2_deliver Message-ID: <20180816085324.54F349C4E3@lists.varnish-cache.org> commit 8a564bb556d4eff6632641cd820d0dbd9dba4459 Author: Dag Haavi Finstad Date: Mon Aug 13 11:32:10 2018 +0200 Fix a buffer overflow situation in h2_deliver This still lacks error handling and thus is not a fix for #2589, but at least we're not writing past the end of the workspace any more. diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c index cb9c7d3f2..a36d657c0 100644 --- a/bin/varnishd/http2/cache_http2_deliver.c +++ b/bin/varnishd/http2/cache_http2_deliver.c @@ -160,34 +160,35 @@ h2_minimal_response(struct req *req, uint16_t status) return (0); } -static uint8_t * -h2_enc_len(uint8_t *p, unsigned bits, unsigned val) +static int +h2_enc_len(struct vsb *vsb, unsigned bits, unsigned val, uint8_t b0) { assert(bits < 8); unsigned mask = (1U << bits) - 1U; if (val >= mask) { - *p++ |= (uint8_t)mask; + AZ(VSB_putc(vsb, b0 | (uint8_t)mask)); val -= mask; while (val >= 128) { - *p++ = 0x80 | ((uint8_t)val & 0x7f); + AZ(VSB_putc(vsb, 0x80 | ((uint8_t)val & 0x7f))); val >>= 7; } } - *p++ = (uint8_t)val; - return (p); + AZ(VSB_putc(vsb, (uint8_t)val)); + return (0); } void v_matchproto_(vtr_deliver_f) h2_deliver(struct req *req, struct boc *boc, int sendbody) { ssize_t sz, sz1; - uint8_t *p; - unsigned u; + unsigned u, l; + uint8_t buf[6]; const char *r; struct http *hp; struct sess *sp; struct h2_req *r2; + struct vsb resp; int i, err; const struct hpack_static *hps; @@ -198,15 +199,14 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) sp = req->sp; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - (void)WS_Reserve(req->ws, 0); - p = (void*)req->ws->f; + l = WS_Reserve(req->ws, 0); + AN(VSB_new(&resp, req->ws->f, l, VSB_FIXEDLEN)); - p += h2_status(p, req->resp->status); + l = h2_status(buf, req->resp->status); + AZ(VSB_bcat(&resp, buf, l)); hp = req->resp; for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { - assert(WS_Inside(req->ws, p, NULL)); - r = strchr(hp->hd[u].b, ':'); AN(r); @@ -227,27 +227,24 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) VSLb(req->vsl, SLT_Debug, "HP {%d, \"%s\", \"%s\"} <%s>", hps->idx, hps->name, hps->val, hp->hd[u].b); - *p = 0x10; - p = h2_enc_len(p, 4, hps->idx); + AZ(h2_enc_len(&resp, 4, hps->idx, 0x10)); } else { - - *p++ = 0x10; + AZ(VSB_putc(&resp, 0x10)); sz--; - p = h2_enc_len(p, 7, sz); + AZ(h2_enc_len(&resp, 7, sz, 0)); for (sz1 = 0; sz1 < sz; sz1++) - *p++ = (uint8_t)tolower(hp->hd[u].b[sz1]); + AZ(VSB_putc(&resp, tolower(hp->hd[u].b[sz1]))); } while (vct_islws(*++r)) continue; sz = hp->hd[u].e - r; - p = h2_enc_len(p, 7, sz); - memcpy(p, r, sz); - p += sz; - assert(WS_Inside(req->ws, p, NULL)); + AZ(h2_enc_len(&resp, 7, sz, 0)); + AZ(VSB_bcat(&resp, r, sz)); } - sz = (char*)p - req->ws->f; + VSB_finish(&resp); + sz = VSB_len(&resp); AZ(req->wrk->v1l); From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:24 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:24 +0000 (UTC) Subject: [6.0] e80c65fdb properly declare vtc_h2_dectbl.h to automake and git Message-ID: <20180816085324.718A29C4F4@lists.varnish-cache.org> commit e80c65fdb0ca0f5aaa38bde8d3d364dd74cb524a Author: Nils Goroll Date: Mon Aug 13 15:35:30 2018 +0200 properly declare vtc_h2_dectbl.h to automake and git in order to have it build first and cleaned up fixes this issue when switching to an older branch: $ git checkout ... error: The following untracked working tree files would be overwritten by checkout: bin/varnishtest/vtc_h2_dectbl.h Please move or remove them before you switch branches. Aborting diff --git a/.gitignore b/.gitignore index cdba66f7f..113da821b 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ cscope.*out # Various auto-generated code snippets /bin/varnishd/vhp_hufdec.h /bin/varnishd/vhp_gen_hufdec +/bin/varnishtest/vtc_h2_dectbl.h /include/vcl.h /include/vrt_obj.h /include/vmod_abi.h diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index b34caa435..5c3cfae85 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -91,4 +91,8 @@ vtc_h2_dectbl.h: huffman_gen.py $(top_srcdir)/include/tbl/vhp_huffman.h $(top_srcdir)/include/tbl/vhp_huffman.h > $@_ mv $@_ $@ -CLEANFILES = $(builddir)/teken_state.h +BUILT_SOURCES = vtc_h2_dectbl.h + +CLEANFILES = \ + $(builddir)/teken_state.h \ + $(BUILT_SOURCES) From dridi.boukelmoune at gmail.com Thu Aug 16 08:53:24 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 08:53:24 +0000 (UTC) Subject: [6.0] 6ffcafc9f Make large integers work in VCL. Message-ID: <20180816085324.B53F49C513@lists.varnish-cache.org> commit 6ffcafc9fd3c379c82b1dba9e43cfe40ae65f122 Author: Poul-Henning Kamp Date: Tue Aug 14 07:45:23 2018 +0000 Make large integers work in VCL. Fixes: #2603 diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index da563157f..4bebb20ae 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -326,10 +326,16 @@ varnish v1 -vcl+backend { set resp.http.foo = (resp.http.foo + resp.http.bar) == ("X" + resp.http.foo); } + sub vcl_deliver { + set resp.http.p = (0 + 9223372036854775807); + set resp.http.n = (0 - 9223372036854775807); + } } -start client c1 { txreq rxresp expect resp.http.foo == "true" + expect resp.http.p == 9223372036854775807 + expect resp.http.n == -9223372036854775807 } -run diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index 05128ec21..ee49f55e4 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -80,6 +80,7 @@ tokens = { # These have handwritten recognizers "ID": None, "CNUM": None, + "FNUM": None, "CSTR": None, "EOI": None, "CSRC": None, diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index fef82ecef..3a6860abe 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -331,7 +331,6 @@ void Emit_UDS_Path(struct vcc *tl, const struct token *t_path, const char *errid); double vcc_TimeUnit(struct vcc *); void vcc_ByteVal(struct vcc *, double *); -void vcc_NumVal(struct vcc *, double *, int *); void vcc_Duration(struct vcc *tl, double *); unsigned vcc_UintVal(struct vcc *tl); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 39a01af38..b420dedf8 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -677,6 +677,7 @@ vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, struct token *t, * '(' ExprCor ')' * symbol * CNUM + * FNUM * CSTR */ @@ -688,7 +689,6 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt) struct token *t; struct symbol *sym; double d; - int i; sign = ""; *e = NULL; @@ -782,34 +782,35 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt) *e = e1; return; case '-': - if (fmt != INT && fmt != REAL && fmt != DURATION) + if (fmt != INT && + fmt != REAL && + fmt != DURATION && + fmt != STRINGS) break; vcc_NextToken(tl); - ExpectErr(tl, CNUM); + if (tl->t->tok != FNUM && tl->t->tok != CNUM) + break; sign = "-"; /* FALLTHROUGH */ + case FNUM: case CNUM: - /* - * XXX: %g may not have enough decimals by default - * XXX: but %a is ugly, isn't it ? - */ assert(fmt != VOID); if (fmt == BYTES) { vcc_ByteVal(tl, &d); ERRCHK(tl); e1 = vcc_mk_expr(BYTES, "%.1f", d); } else { - vcc_NumVal(tl, &d, &i); - ERRCHK(tl); + t = tl->t; + vcc_NextToken(tl); if (tl->t->tok == ID) { - e1 = vcc_mk_expr(DURATION, "%s%g", - sign, d * vcc_TimeUnit(tl)); + e1 = vcc_mk_expr(DURATION, "(%s%.*s) * %g", + sign, PF(t), vcc_TimeUnit(tl)); ERRCHK(tl); - } else if (i || fmt == REAL) - e1 = vcc_mk_expr(REAL, "%s%f", sign, d); - else - e1 = vcc_mk_expr(INT, "%s%jd", - sign, (intmax_t)d); + } else if (fmt == REAL || t->tok == FNUM) { + e1 = vcc_mk_expr(REAL, "%s%.*s", sign, PF(t)); + } else { + e1 = vcc_mk_expr(INT, "%s%.*s", sign, PF(t)); + } } e1->constant = EXPR_CONST; *e = e1; diff --git a/lib/libvcc/vcc_parse.c b/lib/libvcc/vcc_parse.c index a81950a6c..a4bbf1182 100644 --- a/lib/libvcc/vcc_parse.c +++ b/lib/libvcc/vcc_parse.c @@ -275,31 +275,22 @@ vcc_ParseFunction(struct vcc *tl) static void vcc_ParseVcl(struct vcc *tl) { - struct token *tok0, *tok1, *tok2; + struct token *tok0; int syntax; assert(vcc_IdIs(tl->t, "vcl")); tok0 = tl->t; vcc_NextToken(tl); - tok1 = tl->t; - Expect(tl, CNUM); - syntax = (*tl->t->b - '0') * 10; - vcc_NextToken(tl); - Expect(tl, '.'); - vcc_NextToken(tl); - - Expect(tl, CNUM); - tok2 = tl->t; - syntax += (*tl->t->b - '0'); - vcc_NextToken(tl); - - if (tok1->e - tok1->b != 1 || tok2->e - tok2->b != 1) { + Expect(tl, FNUM); + if (tl->t->e - tl->t->b != 3 || tl->t->b[1] != '.') { VSB_printf(tl->sb, "Don't play silly buggers with VCL version numbers\n"); - vcc_ErrWhere2(tl, tok0, tl->t); + vcc_ErrWhere(tl, tl->t); ERRCHK(tl); } + syntax = (tl->t->b[0] - '0') * 10 + (tl->t->b[2] - '0'); + vcc_NextToken(tl); if (syntax < VCL_LOW || syntax > VCL_HIGH) { VSB_printf(tl->sb, "VCL version %.1f not supported.\n", diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c index 894397d1e..fcd37796c 100644 --- a/lib/libvcc/vcc_token.c +++ b/lib/libvcc/vcc_token.c @@ -505,7 +505,15 @@ vcc_Lexer(struct vcc *tl, struct source *sp) for (q = p; q < sp->e; q++) if (!vct_isdigit(*q)) break; - vcc_AddToken(tl, CNUM, p, q); + if (*q != '.') { + vcc_AddToken(tl, CNUM, p, q); + p = q; + continue; + } + for (++q; q < sp->e; q++) + if (!vct_isdigit(*q)) + break; + vcc_AddToken(tl, FNUM, p, q); p = q; continue; } diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c index 71db6a792..b28f1628f 100644 --- a/lib/libvcc/vcc_utils.c +++ b/lib/libvcc/vcc_utils.c @@ -348,50 +348,17 @@ vcc_UintVal(struct vcc *tl) return (d); } -/*-------------------------------------------------------------------- - * Recognize and convert { CNUM [ '.' [ CNUM ] ] } to double value - * The tokenizer made sure we only get digits and a '.' - */ - -void -vcc_NumVal(struct vcc *tl, double *d, int *frac) -{ - double e = 0.1; - const char *p; - - *frac = 0; - *d = 0.0; - Expect(tl, CNUM); - if (tl->err) { - *d = NAN; - return; - } - for (p = tl->t->b; p < tl->t->e; p++) { - *d *= 10; - *d += *p - '0'; - } - vcc_NextToken(tl); - if (tl->t->tok != '.') - return; - *frac = 1; - vcc_NextToken(tl); - if (tl->t->tok != CNUM) - return; - for (p = tl->t->b; p < tl->t->e; p++) { - *d += (*p - '0') * e; - e *= 0.1; - } - vcc_NextToken(tl); -} - static double vcc_DoubleVal(struct vcc *tl) { - double d; - int i; + const size_t l = tl->t->e - tl->t->b; + char buf[l + 1]; - vcc_NumVal(tl, &d, &i); - return (d); + assert(tl->t->tok == CNUM || tl->t->tok == FNUM); + memcpy(buf, tl->t->b, l); + vcc_NextToken(tl); + buf[l] = '\0'; + return (strtod(buf, NULL)); } /*--------------------------------------------------------------------*/ From phk at FreeBSD.org Thu Aug 16 09:25:13 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 16 Aug 2018 09:25:13 +0000 (UTC) Subject: [master] bbc34e2d0 Add a cli send/expect facility to HAproxy support. Message-ID: <20180816092513.50BFA5A9C@lists.varnish-cache.org> commit bbc34e2d0dd8eb5d9cbbe25c52d3f43500b0874d Author: Poul-Henning Kamp Date: Thu Aug 16 09:23:42 2018 +0000 Add a cli send/expect facility to HAproxy support. Submitted by: Frederic Lecaille diff --git a/bin/varnishtest/tests/h00001.vtc b/bin/varnishtest/tests/h00001.vtc index 1b86d81a0..f8b98a2ec 100644 --- a/bin/varnishtest/tests/h00001.vtc +++ b/bin/varnishtest/tests/h00001.vtc @@ -30,3 +30,9 @@ client c1 -connect ${h1_fe1_sock} { expect resp.status == 200 expect resp.body == "s1 >>> Hello world!" } -run + +haproxy h1 -cli { + send "show info" + expect ~ "Name: HAProxy" +} -wait + diff --git a/bin/varnishtest/vtc_haproxy.c b/bin/varnishtest/vtc_haproxy.c index a3e89c713..157d0e67c 100644 --- a/bin/varnishtest/vtc_haproxy.c +++ b/bin/varnishtest/vtc_haproxy.c @@ -34,12 +34,15 @@ #include #include #include /* for MUSL (mode_t) */ +#include +#include #include #include "vtc.h" #include "vfil.h" #include "vpf.h" +#include "vre.h" #include "vtcp.h" #include "vtim.h" @@ -50,6 +53,7 @@ #define HAPROXY_EXPECT_EXIT (128 + HAPROXY_SIGNAL) #define HAPROXY_GOOD_CONF "Configuration file is valid" + struct haproxy { unsigned magic; #define HAPROXY_MAGIC 0x8a45cf75 @@ -73,7 +77,10 @@ struct haproxy { int expect_signal; int its_dead_jim; + /* UNIX socket CLI. */ char *cli_fn; + /* TCP socket CLI. */ + struct haproxy_cli *cli; char *workdir; struct vsb *msgs; @@ -82,6 +89,269 @@ struct haproxy { static VTAILQ_HEAD(, haproxy) haproxies = VTAILQ_HEAD_INITIALIZER(haproxies); +struct haproxy_cli { + unsigned magic; +#define HAPROXY_CLI_MAGIC 0xb09a4ed8 + struct vtclog *vl; + char running; + + char *spec; + + int sock; + char connect[256]; + + pthread_t tp; + size_t txbuf_sz; + char *txbuf; + size_t rxbuf_sz; + char *rxbuf; + + double timeout; +}; + +/********************************************************************** + * Socket connect (same as client_tcp_connect()). + */ + +static int +haproxy_cli_tcp_connect(struct vtclog *vl, const char *addr, double tmo, + const char **errp) +{ + int fd; + char mabuf[32], mpbuf[32]; + + fd = VTCP_open(addr, NULL, tmo, errp); + if (fd < 0) + return fd; + VTCP_myname(fd, mabuf, sizeof mabuf, mpbuf, sizeof mpbuf); + vtc_log(vl, 3, + "CLI connected fd %d from %s %s to %s", fd, mabuf, mpbuf, addr); + return fd; +} + +/* + * SECTION: haproxy.cli haproxy CLI Specification + * SECTION: haproxy.cli.send + * send STRING + * Push STRING on the CLI connection. STRING will be terminated by an + * end of line character (\n). + */ +static void v_matchproto_(cmd_f) +cmd_haproxy_cli_send(CMD_ARGS) +{ + struct vsb *vsb; + struct haproxy_cli *hc; + ssize_t wr; + + (void)cmd; + (void)vl; + CAST_OBJ_NOTNULL(hc, priv, HAPROXY_CLI_MAGIC); + AZ(strcmp(av[0], "send")); + AN(av[1]); + AZ(av[2]); + + vsb = VSB_new_auto(); + AN(vsb); + AZ(VSB_cat(vsb, av[1])); + AZ(VSB_cat(vsb, "\n")); + AZ(VSB_finish(vsb)); + if (hc->sock == -1) { + int fd; + const char *err; + struct vsb *vsb_connect; + + vsb_connect = macro_expand(hc->vl, hc->connect); + AN(vsb_connect); + fd = haproxy_cli_tcp_connect(hc->vl, + VSB_data(vsb_connect), 10., &err); + if (fd < 0) + vtc_fatal(hc->vl, + "CLI failed to open %s: %s", VSB_data(vsb), err); + VSB_destroy(&vsb_connect); + hc->sock = fd; + } + vtc_dump(hc->vl, 4, "CLI send", VSB_data(vsb), -1); + + wr = write(hc->sock, VSB_data(vsb), VSB_len(vsb)); + if (wr != VSB_len(vsb)) + vtc_fatal(hc->vl, + "CLI fd %d send error %s", hc->sock, strerror(errno)); + + VSB_destroy(&vsb); +} + +#define HAPROXY_CLI_RECV_LEN (1 << 14) +static void +haproxy_cli_recv(struct haproxy_cli *hc) +{ + ssize_t ret; + size_t rdz, left, off; + + rdz = ret = off = 0; + /* We want to null terminate this buffer. */ + left = hc->rxbuf_sz - 1; + while (!vtc_error && left > 0) { + VTCP_set_read_timeout(hc->sock, hc->timeout); + + ret = recv(hc->sock, hc->rxbuf + off, HAPROXY_CLI_RECV_LEN, 0); + if (ret < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + + vtc_fatal(hc->vl, + "CLI fd %d recv() failed (%s)", + hc->sock, strerror(errno)); + } + /* Connection closed. */ + if (ret == 0) { + if (hc->rxbuf[rdz - 1] != '\n') + vtc_fatal(hc->vl, + "CLI rx timeout (fd: %d %.3fs ret: %zd)", + hc->sock, hc->timeout, ret); + + vtc_log(hc->vl, 4, "CLI connection normally closed"); + vtc_log(hc->vl, 3, "CLI closing fd %d", hc->sock); + VTCP_close(&hc->sock); + break; + } + + rdz += ret; + left -= ret; + off += ret; + } + hc->rxbuf[rdz] = '\0'; + vtc_dump(hc->vl, 4, "CLI recv", hc->rxbuf, rdz); +} + +/* + * SECTION: haproxy.cli.expect + * expect OP STRING + * Regex match the CLI reception buffer with STRING + * if OP is ~ or, on the contraty, if OP is !~ check that there is + * no regex match. + */ +static void v_matchproto_(cmd_f) +cmd_haproxy_cli_expect(CMD_ARGS) +{ + struct haproxy_cli *hc; + vre_t *vre; + const char *error; + int erroroffset, i, ret; + char *cmp, *spec; + + (void)cmd; + (void)vl; + CAST_OBJ_NOTNULL(hc, priv, HAPROXY_CLI_MAGIC); + AZ(strcmp(av[0], "expect")); + av++; + + cmp = av[0]; + spec = av[1]; + AN(cmp); + AN(spec); + AZ(av[2]); + + assert(!strcmp(cmp, "~") || !strcmp(cmp, "!~")); + + haproxy_cli_recv(hc); + + vre = VRE_compile(spec, 0, &error, &erroroffset); + if (!vre) + vtc_fatal(hc->vl, "CLI regexp error: '%s' (@%d) (%s)", + error, erroroffset, spec); + + i = VRE_exec(vre, hc->rxbuf, strlen(hc->rxbuf), 0, 0, NULL, 0, 0); + + VRE_free(&vre); + + ret = (i >= 0 && *cmp == '~') || (i < 0 && *cmp == '!'); + if (!ret) + vtc_fatal(hc->vl, "CLI expect failed %s \"%s\"", cmp, spec); + else + vtc_log(hc->vl, 4, "CLI expect match %s \"%s\"", cmp, spec); +} + +static const struct cmds haproxy_cli_cmds[] = { +#define CMD_HAPROXY_CLI(n) { #n, cmd_haproxy_cli_##n }, + CMD_HAPROXY_CLI(send) + CMD_HAPROXY_CLI(expect) +#undef CMD_HAPROXY_CLI +}; + +/********************************************************************** + * HAProxy CLI client thread + */ + +static void * +haproxy_cli_thread(void *priv) +{ + struct haproxy_cli *hc; + struct vsb *vsb; + int fd; + const char *err; + + CAST_OBJ_NOTNULL(hc, priv, HAPROXY_CLI_MAGIC); + AN(*hc->connect); + + vsb = macro_expand(hc->vl, hc->connect); + AN(vsb); + + fd = haproxy_cli_tcp_connect(hc->vl, VSB_data(vsb), 10., &err); + if (fd < 0) + vtc_fatal(hc->vl, + "CLI failed to open %s: %s", VSB_data(vsb), err); + (void)VTCP_blocking(fd); + hc->sock = fd; + parse_string(hc->spec, haproxy_cli_cmds, hc, hc->vl); + vtc_log(hc->vl, 2, "CLI ending"); + VSB_destroy(&vsb); + return (NULL); +} + +/********************************************************************** + * Wait for the CLI client thread to stop + */ + +static void +haproxy_cli_wait(struct haproxy_cli *hc) +{ + void *res; + + CHECK_OBJ_NOTNULL(hc, HAPROXY_CLI_MAGIC); + vtc_log(hc->vl, 2, "CLI waiting"); + AZ(pthread_join(hc->tp, &res)); + if (res != NULL) + vtc_fatal(hc->vl, "CLI returned \"%s\"", (char *)res); + REPLACE(hc->spec, NULL); + hc->tp = 0; + hc->running = 0; +} + +/********************************************************************** + * Start the CLI client thread + */ + +static void +haproxy_cli_start(struct haproxy_cli *hc) +{ + CHECK_OBJ_NOTNULL(hc, HAPROXY_CLI_MAGIC); + vtc_log(hc->vl, 2, "CLI starting"); + AZ(pthread_create(&hc->tp, NULL, haproxy_cli_thread, hc)); + hc->running = 1; + +} + +/********************************************************************** + * Run the CLI client thread + */ + +static void +haproxy_cli_run(struct haproxy_cli *hc) +{ + haproxy_cli_start(hc); + haproxy_cli_wait(hc); +} + /********************************************************************** * */ @@ -131,6 +401,41 @@ haproxy_wait_pidfile(struct haproxy *h) h->name, buf_err); } +/********************************************************************** + * Allocate and initialize a CLI client + */ + +static struct haproxy_cli * +haproxy_cli_new(struct haproxy *h) +{ + struct haproxy_cli *hc; + + ALLOC_OBJ(hc, HAPROXY_CLI_MAGIC); + AN(hc); + + hc->vl = h->vl; + hc->sock = -1; + bprintf(hc->connect, "${%s_cli_sock}", h->name); + + hc->txbuf_sz = hc->rxbuf_sz = 2048 * 1024; + hc->txbuf = malloc(hc->txbuf_sz); + AN(hc->txbuf); + hc->rxbuf = malloc(hc->rxbuf_sz); + AN(hc->rxbuf); + + return hc; +} + +static void +haproxy_cli_delete(struct haproxy_cli *hc) +{ + CHECK_OBJ_NOTNULL(hc, HAPROXY_CLI_MAGIC); + REPLACE(hc->spec, NULL); + REPLACE(hc->txbuf, NULL); + REPLACE(hc->rxbuf, NULL); + FREE_OBJ(hc); +} + /********************************************************************** * Allocate and initialize a haproxy */ @@ -170,6 +475,9 @@ haproxy_new(const char *name) h->cfg_fn = strdup(buf); AN(h->cfg_fn); + h->cli = haproxy_cli_new(h); + AN(h->cli); + bprintf(buf, "rm -rf %s ; mkdir -p %s", h->workdir, h->workdir); AZ(system(buf)); @@ -201,6 +509,7 @@ haproxy_delete(struct haproxy *h) free(h->cfg_fn); free(h->pid_fn); VSB_destroy(&h->args); + haproxy_cli_delete(h->cli); /* XXX: MEMLEAK (?) */ FREE_OBJ(h); @@ -323,6 +632,9 @@ haproxy_wait(struct haproxy *h) if (h->pid < 0) haproxy_start(h); + if (h->cli->spec) + haproxy_cli_run(h->cli); + closefd(&h->fds[1]); sig = SIGINT; @@ -445,6 +757,7 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) VSB_printf(vsb, " global\n\tstats socket %s " "level admin mode 600\n", h->cli_fn); + VSB_printf(vsb, " stats socket \"fd@${cli}\" level admin\n"); AZ(VSB_cat(vsb, cfg)); if (auto_be) @@ -508,6 +821,9 @@ haproxy_write_conf(const struct haproxy *h, const char *cfg, int auto_be) * \-arg STRING * Pass an argument to haproxy, for example "-h simple_list". * + * \-cli STRING + * Specify the spec to be run by the command line interface (CLI). + * * \-conf STRING * Specify the configuration to be loaded by this HAProxy instance. * @@ -598,6 +914,13 @@ cmd_haproxy(CMD_ARGS) continue; } + if (!strcmp(*av, "-cli")) { + REPLACE(h->cli->spec, av[1]); + if (h->tp) + haproxy_cli_run(h->cli); + av++; + continue; + } if (!strcmp(*av, "-conf")) { AN(av[1]); haproxy_write_conf(h, av[1], 0); From dridi.boukelmoune at gmail.com Thu Aug 16 09:36:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 09:36:08 +0000 (UTC) Subject: [6.0] e6ef7ee2d Fix r02702's -cliexpect Message-ID: <20180816093608.7ADA16256B@lists.varnish-cache.org> commit e6ef7ee2da6d59235807157c6b7150718bf57477 Author: Dridi Boukelmoune Date: Thu Aug 16 11:32:56 2018 +0200 Fix r02702's -cliexpect The output changes in Varnish 6.1 and that check slipped through the cracks. diff --git a/bin/varnishtest/tests/r02702.vtc b/bin/varnishtest/tests/r02702.vtc index c9a938a90..c3b796555 100644 --- a/bin/varnishtest/tests/r02702.vtc +++ b/bin/varnishtest/tests/r02702.vtc @@ -29,7 +29,7 @@ varnish v1 -vcl { delay 1 -varnish v1 -cliexpect "vcl1.s1[ ]+probe[ ]+1/1[ ]+good" backend.list +varnish v1 -cliexpect "vcl1.s1[ ]+probe[ ]+Healthy[ ]+1/1" backend.list # For PROXYv2, we apply a trick similar to o0000[24].vtc, since # Varnish accepts (and ignores) PROXY LOCAL. @@ -63,7 +63,7 @@ server s1 -wait delay 1 -varnish v3 -cliexpect "vcl1.bp[ ]+probe[ ]+1/1[ ]+good" backend.list +varnish v3 -cliexpect "vcl1.bp[ ]+probe[ ]+Healthy[ ]+1/1" backend.list # Verify in the v2 log that PROXY LOCAL was sent. From dridi.boukelmoune at gmail.com Thu Aug 16 10:21:09 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Thu, 16 Aug 2018 10:21:09 +0000 (UTC) Subject: [6.0] 735287af9 Use 'S' as instance-id for syslog. Message-ID: <20180816102109.385C891D1A@lists.varnish-cache.org> commit 735287af9206f7bab6a84904b24d9e9b8a290790 Author: Poul-Henning Kamp Date: Tue May 29 16:00:55 2018 +0000 Use 'S' as instance-id for syslog. diff --git a/bin/varnishtest/tests/h00005.vtc b/bin/varnishtest/tests/h00005.vtc index 66427b5a4..098bf19ab 100644 --- a/bin/varnishtest/tests/h00005.vtc +++ b/bin/varnishtest/tests/h00005.vtc @@ -8,7 +8,7 @@ server s1 { txresp } -start -syslog sl1 -level notice -bind "127.0.0.1:0" { +syslog S1 -level notice -bind "127.0.0.1:0" { recv recv recv info @@ -17,7 +17,7 @@ syslog sl1 -level notice -bind "127.0.0.1:0" { haproxy h1 -conf { global - log ${sl1_addr}:${sl1_port} local0 + log ${S1_addr}:${S1_port} local0 defaults log global @@ -41,5 +41,5 @@ client c1 -connect ${h1_fe_1_sock} { rxresp } -run -syslog sl1 -wait +syslog S1 -wait diff --git a/bin/varnishtest/vtc_syslog.c b/bin/varnishtest/vtc_syslog.c index 2ef8a8559..4221b40eb 100644 --- a/bin/varnishtest/vtc_syslog.c +++ b/bin/varnishtest/vtc_syslog.c @@ -247,7 +247,7 @@ syslog_new(const char *name, struct vtclog *vl) { struct syslog_srv *s; - VTC_CHECK_NAME(vl, name, "Syslog", 's'); + VTC_CHECK_NAME(vl, name, "Syslog", 'S'); ALLOC_OBJ(s, SYSLOG_SRV_MAGIC); AN(s); REPLACE(s->name, name); @@ -511,16 +511,16 @@ syslog_wait(struct syslog_srv *s) /* SECTION: syslog syslog * - * Define and interact with syslog instances. + * Define and interact with syslog instances (for use with haproxy) * * To define a syslog server, you'll use this syntax:: * - * syslog sNAME + * syslog SNAME * * Arguments: * - * sNAME - * Identify the syslog server with a string which must start with 's'. + * SNAME + * Identify the syslog server with a string which must start with 'S'. * * \-level STRING * Set the default syslog priority level used by any subsequent "recv" From geoff at uplex.de Thu Aug 16 20:11:05 2018 From: geoff at uplex.de (Geoff Simmons) Date: Thu, 16 Aug 2018 20:11:05 +0000 (UTC) Subject: [master] d9f31889b VMOD blob uses STRANDS instead of STRING_LIST. Message-ID: <20180816201105.A23CCA07D0@lists.varnish-cache.org> commit d9f31889b3ff4b9a88c96f83e67be1df3f33071e Author: Geoff Simmons Date: Thu Aug 16 22:09:18 2018 +0200 VMOD blob uses STRANDS instead of STRING_LIST. diff --git a/lib/libvmod_blob/base64.c b/lib/libvmod_blob/base64.c index 201702962..3bea94871 100644 --- a/lib/libvmod_blob/base64.c +++ b/lib/libvmod_blob/base64.c @@ -29,12 +29,12 @@ #include "config.h" #include -#include "base64.h" - #include "vdef.h" #include "vrt.h" #include "vas.h" +#include "base64.h" + #define base64_l(l) (((l) << 2) / 3) size_t @@ -133,7 +133,7 @@ base64_encode(const enum encoding enc, const enum case_e kase, ssize_t base64_decode(const enum encoding dec, char *restrict const buf, const size_t buflen, ssize_t inlen, - const char *const p, va_list ap) + const struct strands *restrict const strings) { const struct b64_alphabet *alpha = &b64_alphabet[dec]; char *dest = buf; @@ -143,12 +143,14 @@ base64_decode(const enum encoding dec, char *restrict const buf, AN(buf); AN(alpha); + AN(strings); if (inlen >= 0) len = inlen; - for (const char *s = p; len > 0 && s != vrt_magic_string_end; - s = va_arg(ap, const char *)) { + for (int i = 0; len > 0 && i < strings->n; i++) { + const char *s = strings->p[i]; + if (s == NULL) continue; if (*s && term) { diff --git a/lib/libvmod_blob/hex.c b/lib/libvmod_blob/hex.c index 4124100f4..e17dd8960 100644 --- a/lib/libvmod_blob/hex.c +++ b/lib/libvmod_blob/hex.c @@ -30,13 +30,14 @@ #include #include -#include "vmod_blob.h" #include "hex.h" #include "vdef.h" #include "vrt.h" #include "vas.h" +#include "vmod_blob.h" + const char hex_alphabet[][16] = { "0123456789abcdef", "0123456789ABCDEF" @@ -103,20 +104,20 @@ hex_encode(const enum encoding enc, const enum case_e kase, ssize_t hex_decode(const enum encoding dec, char *restrict const buf, const size_t buflen, ssize_t n, - const char *restrict const p, va_list ap) + const struct strands *restrict const strings) { char *dest = buf; const char *b; unsigned char extranib = 0; ssize_t len = 0; - va_list ap2; AN(buf); + AN(strings); assert(dec == HEX); - va_copy(ap2, ap); - for (const char *s = p; s != vrt_magic_string_end; - s = va_arg(ap2, const char *)) { + for (int i = 0; i < strings->n; i++) { + const char *s = strings->p[i]; + if (s == NULL) continue; b = s; @@ -130,7 +131,6 @@ hex_decode(const enum encoding dec, char *restrict const buf, break; len += s - b; } - va_end(ap2); if (len == 0) return 0; @@ -150,8 +150,9 @@ hex_decode(const enum encoding dec, char *restrict const buf, len++; } - for (const char *s = p; len > 0 && s != vrt_magic_string_end; - s = va_arg(ap, const char *)) { + for (int i = 0; len > 0 && i < strings->n; i++) { + const char *s = strings->p[i]; + if (s == NULL || *s == '\0') continue; if (extranib) { diff --git a/lib/libvmod_blob/id.c b/lib/libvmod_blob/id.c index d10e64250..1164e983d 100644 --- a/lib/libvmod_blob/id.c +++ b/lib/libvmod_blob/id.c @@ -30,12 +30,12 @@ #include #include -#include "vmod_blob.h" - #include "vdef.h" #include "vrt.h" #include "vas.h" +#include "vmod_blob.h" + size_t id_encode_l(size_t l) { @@ -69,20 +69,21 @@ id_encode(const enum encoding enc, const enum case_e kase, ssize_t id_decode(const enum encoding enc, char *restrict const buf, const size_t buflen, - ssize_t n, const char *restrict const p, va_list ap) + ssize_t n, const struct strands *restrict const strings) { char *dest = buf; size_t outlen = 0, c = SIZE_MAX; (void) enc; AN(buf); + AN(strings); if (n >= 0) c = n; - for (const char *s = p; c > 0 && s != vrt_magic_string_end; - s = va_arg(ap, const char *)) { + for (int i = 0; c > 0 && i < strings->n; i++) { size_t len; + const char *s = strings->p[i]; if (s == NULL || *s == '\0') continue; diff --git a/lib/libvmod_blob/url.c b/lib/libvmod_blob/url.c index 84f5d0f22..acb55a6bb 100644 --- a/lib/libvmod_blob/url.c +++ b/lib/libvmod_blob/url.c @@ -29,13 +29,14 @@ #include "config.h" #include -#include "vmod_blob.h" #include "hex.h" #include "vdef.h" #include "vrt.h" #include "vas.h" +#include "vmod_blob.h" + /* Decoder states */ enum state_e { NORMAL, @@ -115,8 +116,8 @@ url_encode(const enum encoding enc, const enum case_e kase, ssize_t url_decode(const enum encoding dec, char *restrict const buf, - const size_t buflen, ssize_t n, const char *restrict const p, - va_list ap) + const size_t buflen, ssize_t n, + const struct strands *restrict const strings) { char *dest = buf; const char * const end = buf + buflen; @@ -125,13 +126,15 @@ url_decode(const enum encoding dec, char *restrict const buf, enum state_e state = NORMAL; AN(buf); + AN(strings); assert(dec == URL); if (n >= 0 && (size_t)n < len) len = n; - for (const char *s = p; len > 0 && s != vrt_magic_string_end; - s = va_arg(ap, const char *)) { + for (int i = 0; len > 0 && i < strings->n; i++) { + const char *s = strings->p[i]; + if (s == NULL || *s == '\0') continue; while (*s && len) { diff --git a/lib/libvmod_blob/vmod.vcc b/lib/libvmod_blob/vmod.vcc index 0a7e652d5..a6514dd2e 100644 --- a/lib/libvmod_blob/vmod.vcc +++ b/lib/libvmod_blob/vmod.vcc @@ -176,7 +176,7 @@ affect alphabetic characters that are not percent-encoded. $Function BLOB decode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} decoding="IDENTITY", INT length=0, - STRING_LIST encoded) + STRANDS encoded) Returns the BLOB derived from the string ``encoded`` according to the scheme specified by ``decoding``. @@ -231,7 +231,7 @@ $Function STRING transcode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} encoding="IDENTITY", ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT", - INT length=0, STRING_LIST encoded) + INT length=0, STRANDS encoded) Translates from one encoding to another, by first decoding the string ``encoded`` according to the scheme ``decoding``, and then returning @@ -300,7 +300,7 @@ BLOB. $Object blob(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX, URL} decoding="IDENTITY", - STRING_LIST encoded) + STRANDS encoded) Creates an object that contains the BLOB derived from the string ``encoded`` according to the scheme ``decoding``. diff --git a/lib/libvmod_blob/vmod_blob.c b/lib/libvmod_blob/vmod_blob.c index 632580e91..013533ae9 100644 --- a/lib/libvmod_blob/vmod_blob.c +++ b/lib/libvmod_blob/vmod_blob.c @@ -133,16 +133,15 @@ parse_case(VCL_ENUM e) static inline size_t -decode_l_va(enum encoding dec, const char * const p, va_list ap) +decode_l(enum encoding dec, VCL_STRANDS s) { size_t len = 0; AENC(dec); - for (const char *s = p; s != vrt_magic_string_end; - s = va_arg(ap, const char *)) - if (s != NULL && *s != '\0') - len += strlen(s); + for (int i = 0; i < s->n; i++) + if (s->p[i] != NULL && *s->p[i] != '\0') + len += strlen(s->p[i]); return(func[dec].decode_l(len)); } @@ -185,11 +184,10 @@ check_enc_case(VRT_CTX, VCL_ENUM encs, VCL_ENUM case_s, enum encoding enc, VCL_VOID v_matchproto_(td_blob_blob__init) vmod_blob__init(VRT_CTX, struct vmod_blob_blob **blobp, const char *vcl_name, - VCL_ENUM decs, const char *p, ...) + VCL_ENUM decs, VCL_STRANDS strings) { struct vmod_blob_blob *b; enum encoding dec = parse_encoding(decs); - va_list ap; ssize_t len; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); @@ -197,6 +195,7 @@ vmod_blob__init(VRT_CTX, struct vmod_blob_blob **blobp, const char *vcl_name, AZ(*blobp); AN(vcl_name); AENC(dec); + AN(strings); ALLOC_OBJ(b, VMOD_BLOB_MAGIC); AN(b); @@ -204,9 +203,7 @@ vmod_blob__init(VRT_CTX, struct vmod_blob_blob **blobp, const char *vcl_name, b->blob.free = NULL; AZ(pthread_mutex_init(&b->lock, NULL)); - va_start(ap, p); - len = decode_l_va(dec, p, ap); - va_end(ap); + len = decode_l(dec, strings); if (len == 0) { b->blob.len = 0; b->blob.priv = NULL; @@ -220,17 +217,15 @@ vmod_blob__init(VRT_CTX, struct vmod_blob_blob **blobp, const char *vcl_name, return; } - va_start(ap, p); errno = 0; - len = func[dec].decode(dec, b->blob.priv, len, -1, p, ap); - va_end(ap); + len = func[dec].decode(dec, b->blob.priv, len, -1, strings); if (len == -1) { assert(errno == EINVAL); free(b->blob.priv); b->blob.priv = NULL; VERR(ctx, "cannot create blob %s, illegal encoding beginning " - "with \"%s\"", vcl_name, p); + "with \"%s\"", vcl_name, strings->p[0]); return; } if (len == 0) { @@ -331,31 +326,10 @@ vmod_blob__fini(struct vmod_blob_blob **blobp) /* Functions */ -static inline const char * -find_nonempty_va(const char *restrict *p, va_list ap) -{ - const char *q; - - /* find first non-empty vararg */ - for (; *p == vrt_magic_string_end || *p == NULL || **p == '\0'; - *p = va_arg(ap, char *)) - if (*p == vrt_magic_string_end) - return (vrt_magic_string_end); - - /* find next non-empty vararg */ - for (q = va_arg(ap, const char *); - q != vrt_magic_string_end && (q == NULL || *q == '\0'); - q = va_arg(ap, const char *)) - ; - - return (q); -} - VCL_BLOB v_matchproto_(td_blob_decode) -vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...) +vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, VCL_STRANDS strings) { enum encoding dec = parse_encoding(decs); - va_list ap; struct vmod_priv *b; char *buf; uintptr_t snap; @@ -364,6 +338,7 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AENC(dec); + AN(strings); CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); snap = WS_Snapshot(ctx->ws); @@ -377,13 +352,11 @@ vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...) if (length <= 0) length = -1; - va_start(ap, p); errno = 0; - len = func[dec].decode(dec, buf, space, length, p, ap); - va_end(ap); + len = func[dec].decode(dec, buf, space, length, strings); if (len == -1) { - err_decode(ctx, p); + err_decode(ctx, strings->p[0]); WS_Release(ctx->ws, 0); WS_Reset(ctx->ws, snap); return NULL; @@ -450,17 +423,17 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_ENUM case_s, VCL_BLOB b) VCL_STRING v_matchproto_(td_blob_transcode) vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s, - VCL_INT length, const char *p, ...) + VCL_INT length, VCL_STRANDS strings) { enum encoding dec = parse_encoding(decs); enum encoding enc = parse_encoding(encs); enum case_e kase = parse_case(case_s); - va_list ap; struct vmod_priv b; VCL_STRING r; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC); + AN(strings); AENC(dec); AENC(enc); @@ -472,9 +445,7 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s, * Allocate space for the decoded blob on the stack * ignoring the limitation imposed by n */ - va_start(ap, p); - size_t l = decode_l_va(dec, p, ap); - va_end(ap); + size_t l = decode_l(dec, strings); if (l == 0) return ""; /* XXX: handle stack overflow? */ @@ -484,39 +455,28 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s, if (length <= 0) length = -1; - va_start(ap, p); errno = 0; - b.len = func[dec].decode(dec, buf, l, length, p, ap); - va_end(ap); + b.len = func[dec].decode(dec, buf, l, length, strings); if (b.len == -1) { - err_decode(ctx, p); + err_decode(ctx, strings->p[0]); return NULL; } /* * If the encoding and decoding are the same, and the decoding was - * legal, just return the string, if there was only one in the - * STRING_LIST, or else the concatenated string. + * legal, just return the concatenated string. * For encodings with hex digits, we cannot assume the same result. * since the call may specify upper- or lower-case that differs * from the encoded string. */ - if (length == -1 && enc == dec && !encodes_hex(enc)) { - const char *q, *pp = p; - va_start(ap, p); - q = find_nonempty_va(&pp, ap); - va_end(ap); - - if (pp == vrt_magic_string_end) - return ""; - - if (q == vrt_magic_string_end) - return pp; - - r = VRT_String(ctx->ws, NULL, p, ap); - return r; - } + if (length == -1 && enc == dec && !encodes_hex(enc)) + /* + * Returns NULL and invokes VCL failure on workspace + * overflow. If there is only one string already in the + * workspace, then it is re-used. + */ + return (VRT_CollectStrands(ctx, strings)); r = encode(ctx, enc, kase, &b); return (r); diff --git a/lib/libvmod_blob/vmod_blob.h b/lib/libvmod_blob/vmod_blob.h index e47dff8e7..032f59986 100644 --- a/lib/libvmod_blob/vmod_blob.h +++ b/lib/libvmod_blob/vmod_blob.h @@ -26,8 +26,9 @@ * */ +/* vrt.h must be included before this header (for struct strands). */ + #include -#include #include enum encoding { @@ -86,19 +87,18 @@ ssize_t encode_f(const enum encoding enc, const enum case_e kase, /* * General interface for a decoder: decode the concatenation of strings - * in p and ap (obtained from a STRING_LIST) into buf, and return the - * length of decoded data. + * (obtained from STRANDS) into buf, and return the length of decoded + * data. * * dec: decoding enum (from parse_encoding.h) * buf: destination of the decoded data * buflen: maximum length available at buf * inlen: maximum length to read or -1 to read up to \0 - * p, ap: strings obtained from a VCL STRING_LIST + * strings: strings obtained from VCL STRANDS * - * The regions pointed to by buf and any of the strings in p or ap MUST - * NOT overlap (per restrict). - * Note that the p,ap list is terminated by vrt_magic_string_end, and - * any member of the list may be NULL or empty. + * The regions pointed to by buf and strings MUST NOT overlap (per + * restrict). + * Note that any member of the strings list may be NULL or empty. * * Returns: * -1, if there is insufficient space at buf, or if the decoding is @@ -110,7 +110,7 @@ ssize_t encode_f(const enum encoding enc, const enum case_e kase, typedef ssize_t decode_f(const enum encoding dec, char *restrict const buf, const size_t buflen, const ssize_t inlen, - const char *restrict const p, va_list ap); + const struct strands *restrict const strings); /* id.c */ len_f id_encode_l; From geoff at uplex.de Fri Aug 17 05:14:11 2018 From: geoff at uplex.de (Geoff Simmons) Date: Fri, 17 Aug 2018 05:14:11 +0000 (UTC) Subject: [master] d39082545 Fix showing STRANDS as STRING in the docs. Message-ID: <20180817051411.A54D7A9A13@lists.varnish-cache.org> commit d3908254562013dc45a5b67c9815ded55fb8f98e Author: Geoff Simmons Date: Fri Aug 17 07:13:22 2018 +0200 Fix showing STRANDS as STRING in the docs. diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index 669450fb7..66e99b236 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -239,14 +239,14 @@ class CType(object): assert w == "," def vcl(self): - if self.vt in ("STRING_LIST", "STRAND"): + if self.vt in ("STRING_LIST", "STRANDS"): return "STRING" if self.spec is None: return self.vt return self.vt + " {" + ", ".join(self.spec) + "}" def synopsis(self): - if self.vt in ("STRING_LIST", "STRAND"): + if self.vt in ("STRING_LIST", "STRANDS"): return "STRING" return self.vt From geoff at uplex.de Fri Aug 17 16:31:08 2018 From: geoff at uplex.de (Geoff Simmons) Date: Fri, 17 Aug 2018 16:31:08 +0000 (UTC) Subject: [master] 4c91662cc Start skeleton docs for the September 2018 release notes. Message-ID: <20180817163109.01D8163DA4@lists.varnish-cache.org> commit 4c91662cc65f12dbcfab2c0328a66985b2f04b93 Author: Geoff Simmons Date: Fri Aug 17 18:30:21 2018 +0200 Start skeleton docs for the September 2018 release notes. diff --git a/doc/sphinx/whats-new/changes-6.1.rst b/doc/sphinx/whats-new/changes-6.1.rst new file mode 100644 index 000000000..ee3644694 --- /dev/null +++ b/doc/sphinx/whats-new/changes-6.1.rst @@ -0,0 +1,13 @@ +.. _whatsnew_changes_6.1: + +**NOTE: The present document is work in progress for the September +2018 release.** The version number 6.1.0 is provisional and may +change. See :ref:`whatsnew_changes_6.0` for notes about the currently +most recent Varnish release. + +Changes in Varnish 6.1 +====================== + +**XXX** + +*eof* diff --git a/doc/sphinx/whats-new/index.rst b/doc/sphinx/whats-new/index.rst index 1974cdb0c..54438108b 100644 --- a/doc/sphinx/whats-new/index.rst +++ b/doc/sphinx/whats-new/index.rst @@ -8,6 +8,19 @@ This section describes the changes and improvements between different versions of Varnish, and what upgrading between the different versions entail. +Varnish 6.1 +----------- + +**NOTE: This documentation is work in progress for the September 2018 +release.** The version number 6.1.0 is provisional and may change. See +the links listed below for notes about released versions of Varnish. + +.. toctree:: + :maxdepth: 2 + + changes-6.1 + upgrading-6.1 + Varnish 6.0 ----------- diff --git a/doc/sphinx/whats-new/upgrading-6.1.rst b/doc/sphinx/whats-new/upgrading-6.1.rst new file mode 100644 index 000000000..40bf30224 --- /dev/null +++ b/doc/sphinx/whats-new/upgrading-6.1.rst @@ -0,0 +1,87 @@ +.. _whatsnew_upgrading_6.1: + +**NOTE: The present document is work in progress for the September +2018 release.** The version number 6.1.0 is provisional and may +change. See :ref:`whatsnew_upgrading_6.0` for notes about the +currently most recent Varnish release. + +%%%%%%%%%%%%%%%%%%%%%%%% +Upgrading to Varnish 6.1 +%%%%%%%%%%%%%%%%%%%%%%%% + +.. _upd_6_1_headline: + +**Headline Changes** +==================== + +**XXX** + +varnishd parameters +=================== + +**XXX** + +Changes to VCL +============== + +**Headline VCL changes** +~~~~~~~~~~~~~~~~~~~~~~~~ + +**XXX** + +VCL variables +~~~~~~~~~~~~~ + +``var1`` +-------- + +**XXX** + +``var2`` +-------- + +**XXX** + +**etc** +~~~~~~~ + +**XXX** + +**VMOD changes** +================ + +**XXX** + +**anything else** +================= + +**XXX** + +Other changes +============= + +* ``varnishd(1)``: + + * **XXX** + + * **XXX** + +* ``varnishlog(1)``: + + * **XXX** + + * **XXX** + +* **other binaries in the distribution** + + * **XXX** + + * **XXX** + +* Changes for developers: + + * **XXX** + + * **XXX** + +*eof* From geoff at uplex.de Mon Aug 20 08:05:12 2018 From: geoff at uplex.de (Geoff Simmons) Date: Mon, 20 Aug 2018 08:05:12 +0000 (UTC) Subject: [master] 69f6ba512 Add a note about concurrency in the VSC_Iter documentation. Message-ID: <20180820080512.97BBF687E@lists.varnish-cache.org> commit 69f6ba512091f6532a3083727f2a583ff6111f16 Author: Geoff Simmons Date: Mon Aug 20 10:03:56 2018 +0200 Add a note about concurrency in the VSC_Iter documentation. diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h index 82fa89fbd..3ae67290f 100644 --- a/include/vapi/vsc.h +++ b/include/vapi/vsc.h @@ -135,6 +135,10 @@ int VSC_Iter(struct vsc *, struct vsm *, VSC_iter_f *, void *priv); * * The returned points are valid until the next call to VSC_Iter() * + * Not safe for concurrent reads with the same vsc and vsm + * handles. For concurrency, initalize and attach separate + * structs vsc and vsm. + * * Arguments: * vd: The vsm context * func: The callback function From geoff at uplex.de Mon Aug 20 10:52:09 2018 From: geoff at uplex.de (Geoff Simmons) Date: Mon, 20 Aug 2018 10:52:09 +0000 (UTC) Subject: [master] 5087cdfcc Typo Message-ID: <20180820105209.E078361264@lists.varnish-cache.org> commit 5087cdfcc7c275de995173784d5c5a93f9a61764 Author: Geoff Simmons Date: Mon Aug 20 12:51:33 2018 +0200 Typo diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h index 3ae67290f..6976c857b 100644 --- a/include/vapi/vsc.h +++ b/include/vapi/vsc.h @@ -136,7 +136,7 @@ int VSC_Iter(struct vsc *, struct vsm *, VSC_iter_f *, void *priv); * The returned points are valid until the next call to VSC_Iter() * * Not safe for concurrent reads with the same vsc and vsm - * handles. For concurrency, initalize and attach separate + * handles. For concurrency, initialize and attach separate * structs vsc and vsm. * * Arguments: From nils.goroll at uplex.de Tue Aug 21 07:21:10 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 21 Aug 2018 07:21:10 +0000 (UTC) Subject: [master] da700bf19 look for sphinx-build during configure add --with-sphinx-build Message-ID: <20180821072110.C1A7FA3B1B@lists.varnish-cache.org> commit da700bf19b235f8a1790ae99f70ce88c19eddd3b Author: Nils Goroll Date: Tue Aug 21 09:19:16 2018 +0200 look for sphinx-build during configure add --with-sphinx-build ... argument to specify a custom location Fixes #2742 diff --git a/configure.ac b/configure.ac index 3a45477b3..7cbbe53be 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,15 @@ if test "x$RST2MAN" = "xno"; then [rst2man is needed to build Varnish, please install python-docutils.]) fi +AC_ARG_WITH([sphinx-build], + AS_HELP_STRING([--with-sphinx-build=PATH], [Location of sphinx-build (auto)]), + [SPHINX="$withval"], + AC_CHECK_PROGS(SPHINX, [sphinx-build], [no])) +if test "x$SPHINX" = "xno"; then + AC_MSG_ERROR( + [sphinx-build is needed to build Varnish, please install python-sphinx.]) +fi + AC_ARG_WITH([rst2html], AS_HELP_STRING([--with-rst2html=PATH], [Location of rst2html (auto)]), diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am index f2d0df765..5eb2a1361 100644 --- a/doc/sphinx/Makefile.am +++ b/doc/sphinx/Makefile.am @@ -3,7 +3,7 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = sphinx-build -W -q -N +SPHINXBUILD = $(SPHINX) -W -q -N PAPER = a4 BUILDDIR = $(builddir)/build From phk at FreeBSD.org Wed Aug 22 06:54:14 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 06:54:14 +0000 (UTC) Subject: [master] 2ba2cc341 Align handling of STRINGS derived types. Message-ID: <20180822065414.5872B95BB0@lists.varnish-cache.org> commit 2ba2cc341f06d732abed554fc23aa6934e3b9950 Author: Poul-Henning Kamp Date: Wed Aug 22 06:52:48 2018 +0000 Align handling of STRINGS derived types. Fixes: #2745 diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index 4bebb20ae..f269c4d50 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -322,7 +322,10 @@ varnish v1 -vcl+backend { } varnish v1 -vcl+backend { + import debug; sub vcl_deliver { + // Ticket 2745 + debug.sethdr(resp.http.rst, req.restarts); set resp.http.foo = (resp.http.foo + resp.http.bar) == ("X" + resp.http.foo); } @@ -335,6 +338,7 @@ varnish v1 -vcl+backend { client c1 { txreq rxresp + expect resp.http.rst == "0" expect resp.http.foo == "true" expect resp.http.p == 9223372036854775807 expect resp.http.n == -9223372036854775807 diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 3a6860abe..01f2d92c0 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -103,6 +103,7 @@ struct type { const char *name; const char *tostring; vcc_type_t multype; + int stringform; }; #define VCC_TYPE(foo) extern const struct type foo[1]; diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index b420dedf8..4bc8ea5d9 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -73,7 +73,7 @@ vcc_islit(const struct expr *e) static const char * vcc_utype(vcc_type_t t) { - if (t == STRINGS || t == STRING_LIST) + if (t == STRINGS || t->stringform) t = STRING; return (t->name); } @@ -278,7 +278,7 @@ vcc_expr_tostring(struct vcc *tl, struct expr **e, vcc_type_t fmt) uint8_t constant = EXPR_VAR; CHECK_OBJ_NOTNULL(*e, EXPR_MAGIC); - assert(fmt == STRINGS || fmt == STRING_LIST || fmt == STRING); + assert(fmt == STRINGS || fmt->stringform); assert(fmt != (*e)->fmt); p = (*e)->fmt->tostring; @@ -361,6 +361,7 @@ vcc_Eval_Handle(struct vcc *tl, struct expr **e, struct token *t, (void)t; (void)tl; AN(sym->rname); + AZ(type->stringform); if (sym->type != STRING && type == STRINGS) { *e = vcc_mk_expr(STRINGS, "\"%s\"", sym->name); @@ -1274,22 +1275,26 @@ vcc_expr0(struct vcc *tl, struct expr **e, vcc_type_t fmt) assert(fmt != STRINGS); *e = NULL; t1 = tl->t; - if (fmt == STRING_LIST || fmt == STRING) + if (fmt->stringform) vcc_expr_cor(tl, e, STRINGS); else vcc_expr_cor(tl, e, fmt); ERRCHK(tl); - assert((*e)->fmt != STRING_LIST && (*e)->fmt != STRING); - - if ((*e)->fmt == STRINGS && fmt == STRING_LIST) - (*e)->fmt = STRING_LIST; - else if ((*e)->fmt == STRINGS && fmt == STRING) - *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL); - else if ((*e)->fmt == STRINGS && fmt == STRANDS) { - *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL); - } else if ((*e)->fmt != STRINGS && - (fmt == STRING || fmt == STRING_LIST)) - vcc_expr_tostring(tl, e, fmt); + assert(!(*e)->fmt->stringform); + + if ((*e)->fmt != STRINGS && fmt->stringform) + vcc_expr_tostring(tl, e, STRINGS); + + if ((*e)->fmt == STRINGS && fmt->stringform) { + if (fmt == STRING_LIST) + (*e)->fmt = STRING_LIST; + else if (fmt == STRING) + *e = vcc_expr_edit(tl, STRING, "\vS", *e, NULL); + else if (fmt == STRANDS) + *e = vcc_expr_edit(tl, STRANDS, "\vT", (*e), NULL); + else + WRONG("Unhandled stringform"); + } if ((*e)->fmt == STRING_LIST) *e = vcc_expr_edit(tl, STRING_LIST, diff --git a/lib/libvcc/vcc_types.c b/lib/libvcc/vcc_types.c index dbeaacb09..2e5660994 100644 --- a/lib/libvcc/vcc_types.c +++ b/lib/libvcc/vcc_types.c @@ -131,11 +131,13 @@ const struct type STEVEDORE[1] = {{ const struct type STRING[1] = {{ .magic = TYPE_MAGIC, .name = "STRING", + .stringform = 1, }}; const struct type STRANDS[1] = {{ .magic = TYPE_MAGIC, .name = "STRANDS", + .stringform = 1, }}; const struct type STRINGS[1] = {{ @@ -147,6 +149,7 @@ const struct type STRINGS[1] = {{ const struct type STRING_LIST[1] = {{ .magic = TYPE_MAGIC, .name = "STRING_LIST", + .stringform = 1, }}; const struct type SUB[1] = {{ From phk at FreeBSD.org Wed Aug 22 07:12:09 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 07:12:09 +0000 (UTC) Subject: [master] 2ad290f79 We don't need stdlib.h unless we compile the code Message-ID: <20180822071210.11F71961FF@lists.varnish-cache.org> commit 2ad290f79a41b9764e38ed5ed3f22239ce326018 Author: Poul-Henning Kamp Date: Wed Aug 22 06:59:51 2018 +0000 We don't need stdlib.h unless we compile the code diff --git a/bin/varnishd/waiter/cache_waiter_epoll.c b/bin/varnishd/waiter/cache_waiter_epoll.c index c48b72396..d0a4c690d 100644 --- a/bin/varnishd/waiter/cache_waiter_epoll.c +++ b/bin/varnishd/waiter/cache_waiter_epoll.c @@ -33,10 +33,10 @@ //lint -e{766} #include "config.h" -#include - #if defined(HAVE_EPOLL_CTL) +#include + #include #include From phk at FreeBSD.org Wed Aug 22 07:12:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 07:12:10 +0000 (UTC) Subject: [master] 9bc248cb8 Always AZ VSB_finish() Message-ID: <20180822071210.2054096201@lists.varnish-cache.org> commit 9bc248cb8fea7b4c89a0a21ae9bd9dc38bf5c5df Author: Poul-Henning Kamp Date: Wed Aug 22 07:00:07 2018 +0000 Always AZ VSB_finish() diff --git a/bin/varnishd/http2/cache_http2_deliver.c b/bin/varnishd/http2/cache_http2_deliver.c index a36d657c0..aea59e9a8 100644 --- a/bin/varnishd/http2/cache_http2_deliver.c +++ b/bin/varnishd/http2/cache_http2_deliver.c @@ -243,7 +243,7 @@ h2_deliver(struct req *req, struct boc *boc, int sendbody) AZ(h2_enc_len(&resp, 7, sz, 0)); AZ(VSB_bcat(&resp, r, sz)); } - VSB_finish(&resp); + AZ(VSB_finish(&resp)); sz = VSB_len(&resp); AZ(req->wrk->v1l); From phk at FreeBSD.org Wed Aug 22 07:12:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 07:12:10 +0000 (UTC) Subject: [master] 5c1380016 Don't overload names from libc. Message-ID: <20180822071210.449DA96204@lists.varnish-cache.org> commit 5c138001688b07c366f62160355524765b6051f7 Author: Poul-Henning Kamp Date: Wed Aug 22 07:00:51 2018 +0000 Don't overload names from libc. diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c index 5ad0849e9..430f3e594 100644 --- a/lib/libvmod_directors/random.c +++ b/lib/libvmod_directors/random.c @@ -75,11 +75,11 @@ vmod_random_resolve(VRT_CTX, VCL_BACKEND dir) static void v_matchproto_(vdi_destroy_f) vmod_random_destroy(VCL_BACKEND dir) { - struct vmod_directors_random *random; + struct vmod_directors_random *rr; - CAST_OBJ_NOTNULL(random, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC); - vdir_delete(&random->vd); - FREE_OBJ(random); + CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC); + vdir_delete(&rr->vd); + FREE_OBJ(rr); } static const struct vdi_methods vmod_random_methods[1] = {{ From phk at FreeBSD.org Wed Aug 22 07:12:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 07:12:10 +0000 (UTC) Subject: [master] 4c8143186 Add missing break Message-ID: <20180822071210.6E20D96209@lists.varnish-cache.org> commit 4c8143186f1d816ca77150c3f99a442d8ff405b5 Author: Poul-Henning Kamp Date: Wed Aug 22 07:08:12 2018 +0000 Add missing break diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 200ec18d0..2e8a8961b 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -354,15 +354,15 @@ VRT_Strands(char *d, size_t dl, VCL_STRANDS s) AN(s); b = d; e = b + dl; - for (int i = 0; i < s->n && b < e; i++) + for (int i = 0; i < s->n; i++) if (s->p[i] != NULL && *s->p[i] != '\0') { x = strlen(s->p[i]); - if (b + x < e) - memcpy(b, s->p[i], x); + if (b + x >= e) + return(NULL); + memcpy(b, s->p[i], x); b += x; } - if (b >= e) - return (NULL); + assert(b < e); *b++ = '\0'; return (b); } diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 3851089cd..41a689732 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -437,6 +437,7 @@ h2_win_adjust(const struct h2_sess *h2, uint32_t oldval, uint32_t newval) * rfc7540,l,2676,2680 */ r2->t_window += (int64_t)newval - oldval; + break; default: break; } From phk at FreeBSD.org Wed Aug 22 07:12:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 07:12:10 +0000 (UTC) Subject: [master] 931ead585 Slight polish Message-ID: <20180822071210.8F2239620D@lists.varnish-cache.org> commit 931ead585eaedfc4916e1d5e0aebdc4f47d13f2f Author: Poul-Henning Kamp Date: Wed Aug 22 07:11:46 2018 +0000 Slight polish diff --git a/lib/libvmod_blob/hex.c b/lib/libvmod_blob/hex.c index e17dd8960..dfdbb3e9e 100644 --- a/lib/libvmod_blob/hex.c +++ b/lib/libvmod_blob/hex.c @@ -109,7 +109,7 @@ hex_decode(const enum encoding dec, char *restrict const buf, char *dest = buf; const char *b; unsigned char extranib = 0; - ssize_t len = 0; + size_t len = 0; AN(buf); AN(strings); @@ -123,25 +123,19 @@ hex_decode(const enum encoding dec, char *restrict const buf, b = s; while (*s) { if (!isxdigit(*s++)) { - len = -1; - break; + errno = EINVAL; + return (-1); } } - if (len == -1) - break; len += s - b; } if (len == 0) return 0; - if (len == -1) { - errno = EINVAL; - return -1; - } if (n != -1 && len > n) len = n; - if ((len+1) >> 1 > buflen) { + if (((len+1) >> 1) > buflen) { errno = ENOMEM; return -1; } From phk at FreeBSD.org Wed Aug 22 07:48:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 07:48:10 +0000 (UTC) Subject: [master] ac4740f20 Allow a string argument to return(fail("Because!")); Message-ID: <20180822074810.7C454972A3@lists.varnish-cache.org> commit ac4740f20d865e31676334e8372e9231c32bba86 Author: Poul-Henning Kamp Date: Wed Aug 22 07:46:39 2018 +0000 Allow a string argument to return(fail("Because!")); Fixes #2694 diff --git a/bin/varnishtest/tests/v00040.vtc b/bin/varnishtest/tests/v00040.vtc index 408169ffe..573da73b6 100644 --- a/bin/varnishtest/tests/v00040.vtc +++ b/bin/varnishtest/tests/v00040.vtc @@ -14,9 +14,15 @@ client c1 { varnish v1 -errvcl {VCL "vcl2" Failed initialization} { sub vcl_init { - return (fail); + return(fail("Do Not Press This Button Again")); } + backend b1 { .host = "${s1_addr}"; } +} +varnish v1 -errvcl {Do Not Press} { + sub vcl_init { + return(fail("Do Not Press This Button Again")); + } backend b1 { .host = "${s1_addr}"; } } diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c index 8e61f271e..ded906870 100644 --- a/lib/libvcc/vcc_action.c +++ b/lib/libvcc/vcc_action.c @@ -217,6 +217,22 @@ vcc_act_return_pass(struct vcc *tl) } /*--------------------------------------------------------------------*/ +static void +vcc_act_return_fail(struct vcc *tl) +{ + ExpectErr(tl, '('); + vcc_NextToken(tl); + Fb(tl, 1, "VRT_fail(ctx,\n"); + tl->indent += INDENT; + vcc_Expr(tl, STRING); + tl->indent -= INDENT; + ERRCHK(tl); + SkipToken(tl, ')'); + Fb(tl, 1, ");\n"); +} + +/*--------------------------------------------------------------------*/ + static void vcc_act_return_synth(struct vcc *tl) { @@ -321,6 +337,8 @@ vcc_act_return(struct vcc *tl, struct token *t, struct symbol *sym) vcc_act_return_vcl(tl); else if (hand == VCL_RET_PASS) vcc_act_return_pass(tl); + else if (hand == VCL_RET_FAIL) + vcc_act_return_fail(tl); else { VSB_printf(tl->sb, "Arguments not allowed.\n"); vcc_ErrWhere(tl, tl->t); From nils.goroll at uplex.de Wed Aug 22 08:04:07 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 22 Aug 2018 08:04:07 +0000 (UTC) Subject: [master] 13d519c6f vcc: vmod function named argument clarifications Message-ID: <20180822080407.F026E97881@lists.varnish-cache.org> commit 13d519c6f8074adade8baf0735e5e2263f2d1a0e Author: Nils Goroll Date: Tue Apr 10 17:48:41 2018 +0200 vcc: vmod function named argument clarifications * either NULL or properly named * only named arguments can be possibly be speficied multiple times * only named arguments can be optional * positional arguments could be missing diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 4bc8ea5d9..acb6f03f4 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -524,7 +524,6 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (!memcmp(vvp->value, "PRIV_", 5)) { fa->result = vcc_priv_arg(tl, vvp->value, sym->name, sym->vmod); - fa->name = ""; continue; } fa->type = VCC_Type(vvp->value); @@ -579,6 +578,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, return; } if (fa->result != NULL) { + AN(fa->name); VSB_printf(tl->sb, "Argument '%s' already used\n", fa->name); vcc_ErrWhere(tl, tl->t); @@ -602,6 +602,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) { n++; if (fa->optional) { + AN(fa->name); bprintf(ssa, "\v1.valid_%s = %d,\n", fa->name, fa->avail); e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL); @@ -611,7 +612,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (fa->result == NULL && fa->val != NULL) fa->result = vcc_mk_expr(fa->type, "%s", fa->val); if (fa->result != NULL && sa != NULL) { - if (fa->name && *fa->name != '\0') + if (fa->name) bprintf(ssa, "\v1.%s = \v2,\n", fa->name); else bprintf(ssa, "\v1.arg%d = \v2,\n", n); @@ -620,8 +621,11 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, e1 = vcc_expr_edit(tl, e1->fmt, "\v1,\n\v2", e1, fa->result); } else if (!fa->optional) { - VSB_printf(tl->sb, "Argument '%s' missing\n", - fa->name); + if (fa->name) + VSB_printf(tl->sb, "Argument '%s' missing\n", + fa->name); + else + VSB_printf(tl->sb, "Argument %d missing\n", n); vcc_ErrWhere(tl, tl->t); } free(fa); From phk at FreeBSD.org Wed Aug 22 08:51:10 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 08:51:10 +0000 (UTC) Subject: [master] df1455d1a Improve VCC error messages. Message-ID: <20180822085110.9F35C989AF@lists.varnish-cache.org> commit df1455d1a7d52a3969b09c0b155cc456b4a3f6a1 Author: Poul-Henning Kamp Date: Wed Aug 22 08:50:12 2018 +0000 Improve VCC error messages. Fixes: #2696 diff --git a/bin/varnishtest/tests/v00018.vtc b/bin/varnishtest/tests/v00018.vtc index bc152ec01..d0a21eb1d 100644 --- a/bin/varnishtest/tests/v00018.vtc +++ b/bin/varnishtest/tests/v00018.vtc @@ -83,7 +83,7 @@ varnish v1 -errvcl {Unknown token '<<' when looking for STRING} { sub vcl_recv { ban (<<); } } -varnish v1 -errvcl {Expected an action, 'if', '{' or '}'} { +varnish v1 -errvcl {Symbol not found} { backend b { .host = "127.0.0.1"; } sub vcl_recv { ban_hash (if); } } @@ -93,7 +93,7 @@ varnish v1 -vcl { sub vcl_recv { ban ("req.url ~ foo"); } } -varnish v1 -errvcl {Expected an action, 'if', '{' or '}'} { +varnish v1 -errvcl "Symbol not found" { backend b { .host = "127.0.0.1"; } sub vcl_recv { kluf ; } } diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc index f269c4d50..e36c720c8 100644 --- a/bin/varnishtest/tests/v00020.vtc +++ b/bin/varnishtest/tests/v00020.vtc @@ -20,7 +20,7 @@ varnish v1 -errvcl {Found: '0' at} { 0; } # VCLs tokenstream. # XXX: A better error message would be desirable -varnish v1 -errvcl {Expected an action, 'if', } " sub vcl_recv { { } { " +varnish v1 -errvcl {Symbol not found} " sub vcl_recv { { } { " varnish v1 -errvcl {Comparison of different types: INT '!=' STRING} { sub vcl_recv { diff --git a/bin/varnishtest/tests/v00021.vtc b/bin/varnishtest/tests/v00021.vtc index 871f8732d..689b3faea 100644 --- a/bin/varnishtest/tests/v00021.vtc +++ b/bin/varnishtest/tests/v00021.vtc @@ -12,13 +12,13 @@ varnish v1 -errvcl {Variable is read only.} { sub vcl_recv { call foo ; } } -varnish v1 -errvcl "Expected an action, 'if', '{' or '}'" { +varnish v1 -errvcl "Symbol not found" { backend b { .host = "127.0.0.1"; } sub vcl_recv { discard; } } -varnish v1 -errvcl "Expected an action, 'if', '{' or '}'" { +varnish v1 -errvcl "Symbol not found" { backend b { .host = "127.0.0.1"; } sub foo { discard; } diff --git a/lib/libvcc/vcc_parse.c b/lib/libvcc/vcc_parse.c index a4bbf1182..cc0c34751 100644 --- a/lib/libvcc/vcc_parse.c +++ b/lib/libvcc/vcc_parse.c @@ -160,7 +160,7 @@ vcc_Compound(struct vcc *tl) vcc_NextToken(tl); tl->indent -= INDENT; Fb(tl, 1, "}\n"); - return; + break; case CSRC: if (tl->allow_inline_c) { Fb(tl, 1, "%.*s\n", @@ -177,25 +177,31 @@ vcc_Compound(struct vcc *tl) VSB_printf(tl->sb, "End of input while in compound statement\n"); tl->err = 1; - return; + break; case ID: sym = VCC_SymbolGet(tl, SYM_NONE, SYMTAB_NOERR, XREF_NONE); - if (sym != NULL && sym->action != NULL) { + if (sym == NULL) { + VSB_printf(tl->sb, "Symbol not found.\n"); + vcc_ErrWhere(tl, tl->t); + } else if (sym->action == NULL) { + VSB_printf(tl->sb, + "Symbol cannot be used here.\n"); + vcc_ErrWhere(tl, tl->t); + } else { if (sym->action_mask != 0) vcc_AddUses(tl, t, NULL, sym->action_mask, "Not a valid action"); sym->action(tl, t, sym); - break; } - /* FALLTHROUGH */ + break; default: /* We deliberately do not mention inline C */ VSB_printf(tl->sb, "Expected an action, 'if', '{' or '}'\n"); vcc_ErrWhere(tl, tl->t); - return; + break; } Fb(tl, 1, "if (*ctx->handling) return;\n"); } From phk at FreeBSD.org Wed Aug 22 09:31:09 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 22 Aug 2018 09:31:09 +0000 (UTC) Subject: [master] 47c8927bd So much for untested "stylistic" changes before commit. Message-ID: <20180822093109.E98F39B899@lists.varnish-cache.org> commit 47c8927bdb090c7154bc15f2e0722324d01831b2 Author: Poul-Henning Kamp Date: Wed Aug 22 09:29:41 2018 +0000 So much for untested "stylistic" changes before commit. In other news: VTEST works. diff --git a/lib/libvcc/vcc_parse.c b/lib/libvcc/vcc_parse.c index cc0c34751..ee8830859 100644 --- a/lib/libvcc/vcc_parse.c +++ b/lib/libvcc/vcc_parse.c @@ -160,7 +160,7 @@ vcc_Compound(struct vcc *tl) vcc_NextToken(tl); tl->indent -= INDENT; Fb(tl, 1, "}\n"); - break; + return; case CSRC: if (tl->allow_inline_c) { Fb(tl, 1, "%.*s\n", @@ -177,31 +177,33 @@ vcc_Compound(struct vcc *tl) VSB_printf(tl->sb, "End of input while in compound statement\n"); tl->err = 1; - break; + return; case ID: sym = VCC_SymbolGet(tl, SYM_NONE, SYMTAB_NOERR, XREF_NONE); if (sym == NULL) { VSB_printf(tl->sb, "Symbol not found.\n"); vcc_ErrWhere(tl, tl->t); - } else if (sym->action == NULL) { + return; + } + if (sym->action == NULL) { VSB_printf(tl->sb, "Symbol cannot be used here.\n"); vcc_ErrWhere(tl, tl->t); - } else { - if (sym->action_mask != 0) - vcc_AddUses(tl, t, NULL, - sym->action_mask, - "Not a valid action"); - sym->action(tl, t, sym); + return; } + if (sym->action_mask != 0) + vcc_AddUses(tl, t, NULL, + sym->action_mask, + "Not a valid action"); + sym->action(tl, t, sym); break; default: /* We deliberately do not mention inline C */ VSB_printf(tl->sb, "Expected an action, 'if', '{' or '}'\n"); vcc_ErrWhere(tl, tl->t); - break; + return; } Fb(tl, 1, "if (*ctx->handling) return;\n"); } From nils.goroll at uplex.de Wed Aug 22 09:40:13 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 22 Aug 2018 09:40:13 +0000 (UTC) Subject: [master] 041f08e80 style(9)-ification Message-ID: <20180822094013.A861C9BD0E@lists.varnish-cache.org> commit 041f08e808602e10380af22265c176aeeab57576 Author: Nils Goroll Date: Wed Aug 22 11:37:32 2018 +0200 style(9)-ification diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index acb6f03f4..e016696a5 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -595,7 +595,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (sa != NULL) e1 = vcc_mk_expr(rfmt, "%s(ctx%s,\v+ &(%s){\n", - cfunc, extra, sa); + cfunc, extra, sa); else e1 = vcc_mk_expr(rfmt, "%s(ctx%s\v+", cfunc, extra); n = 0; @@ -604,7 +604,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, if (fa->optional) { AN(fa->name); bprintf(ssa, "\v1.valid_%s = %d,\n", - fa->name, fa->avail); + fa->name, fa->avail); e1 = vcc_expr_edit(tl, e1->fmt, ssa, e1, NULL); } if (fa->result == NULL && fa->type == ENUM && fa->val != NULL) @@ -623,7 +623,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, } else if (!fa->optional) { if (fa->name) VSB_printf(tl->sb, "Argument '%s' missing\n", - fa->name); + fa->name); else VSB_printf(tl->sb, "Argument %d missing\n", n); vcc_ErrWhere(tl, tl->t); From nils.goroll at uplex.de Wed Aug 22 12:30:12 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 22 Aug 2018 12:30:12 +0000 (UTC) Subject: [master] 85e3d442c avoid running checks twice for real now, hopefully Message-ID: <20180822123012.7114BA0731@lists.varnish-cache.org> commit 85e3d442c7895e96b4a59a697921a8491f820461 Author: Nils Goroll Date: Wed Aug 22 14:26:30 2018 +0200 avoid running checks twice for real now, hopefully Ref: c2888919964c0498c511db5e7158244e15771eab 72bacde7fbffc50c2a62c9988b99d8a830b60d30 46f1557dd80ffbd75fab924e48ecfd020437b1e0 diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am index 5c3cfae85..357ef9269 100644 --- a/bin/varnishtest/Makefile.am +++ b/bin/varnishtest/Makefile.am @@ -5,7 +5,6 @@ TEST_EXTENSIONS = .vtc TESTS = @VTC_TESTS@ # Make sure we run check-local first -check: check-am check-local check-am: check-local # See if list of checks have changed, recheck check-local: From fgsch at lodoss.net Wed Aug 22 14:58:12 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Wed, 22 Aug 2018 14:58:12 +0000 (UTC) Subject: [master] cc51ba948 Rework to hopefully fix the travis osx job Message-ID: <20180822145812.DCDE4A317D@lists.varnish-cache.org> commit cc51ba94814563d54b8c39f916fe480fc872a474 Author: Federico G. Schwindt Date: Wed Aug 22 15:56:56 2018 +0100 Rework to hopefully fix the travis osx job diff --git a/.travis.yml b/.travis.yml index 021ed0de5..4441126b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,7 @@ before_install: brew update brew upgrade python brew install docutils sphinx-doc nghttp2 + export PATH="/usr/local/opt/sphinx-doc/bin:$PATH" elif [[ -n "$CLANG" ]]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-add-repository -y \ @@ -60,7 +61,6 @@ script: - | if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PYTHONPATH=`brew --prefix`/lib/python2.7/site-packages - export PATH="/usr/local/opt/sphinx-doc/bin:$PATH" fi if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then make -j3 distcheck From gquintard at users.noreply.github.com Wed Aug 22 16:21:07 2018 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Wed, 22 Aug 2018 16:21:07 +0000 (UTC) Subject: [master] 3ae6edff5 Expect right after rxreq Message-ID: <20180822162107.04848A4B6D@lists.varnish-cache.org> commit 3ae6edff535108898ba1957bd1e8296f59b1ea3e Author: guillaume quintard Date: Sun Aug 19 11:24:11 2018 -0700 Expect right after rxreq diff --git a/bin/varnishtest/tests/b00065.vtc b/bin/varnishtest/tests/b00065.vtc index c8df453bf..5eb86d8d9 100644 --- a/bin/varnishtest/tests/b00065.vtc +++ b/bin/varnishtest/tests/b00065.vtc @@ -2,8 +2,8 @@ varnishtest "Test that C-L on HEAD request aren't nuked" server s1 { rxreq - txresp -nolen -hdr "content-length: 17" expect req.method == "HEAD" + txresp -nolen -hdr "content-length: 17" } -start varnish v1 -vcl+backend { From gquintard at users.noreply.github.com Wed Aug 22 16:21:06 2018 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Wed, 22 Aug 2018 16:21:06 +0000 (UTC) Subject: [master] 05249f92c Don't mess with C-L when responding to HEAD Message-ID: <20180822162106.EB956A4B6B@lists.varnish-cache.org> commit 05249f92cf26b9120cfcd0dcdccab8f2ea32f004 Author: Guillaume Quintard Date: Thu Aug 16 19:22:52 2018 -0700 Don't mess with C-L when responding to HEAD diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index 686f25452..deecc3434 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -341,7 +341,7 @@ cnt_transmit(struct worker *wrk, struct req *req) struct boc *boc; const char *r; uint16_t status; - int err, sendbody; + int err, sendbody, head; intmax_t clval; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); @@ -363,7 +363,8 @@ cnt_transmit(struct worker *wrk, struct req *req) /* RFC 7230, 3.3.3 */ status = http_GetStatus(req->resp); - if (!strcmp(req->http0->hd[HTTP_HDR_METHOD].b, "HEAD")) { + head = !strcmp(req->http0->hd[HTTP_HDR_METHOD].b, "HEAD"); + if (head) { if (req->objcore->flags & OC_F_PASS) sendbody = -1; else @@ -395,8 +396,8 @@ cnt_transmit(struct worker *wrk, struct req *req) } } - if (sendbody < 0) { - /* Don't touch pass+HEAD C-L */ + if (sendbody < 0 || head) { + /* Don't touch HEAD C-L */ sendbody = 0; } else if (clval >= 0 && clval == req->resp_len) { /* Reuse C-L header */ diff --git a/bin/varnishtest/tests/b00065.vtc b/bin/varnishtest/tests/b00065.vtc new file mode 100644 index 000000000..c8df453bf --- /dev/null +++ b/bin/varnishtest/tests/b00065.vtc @@ -0,0 +1,20 @@ +varnishtest "Test that C-L on HEAD request aren't nuked" + +server s1 { + rxreq + txresp -nolen -hdr "content-length: 17" + expect req.method == "HEAD" +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_fetch { + set bereq.method = "HEAD"; + } +} -start + +client c1 { + txreq -req HEAD -hdr "connection: close" + rxresphdrs + expect resp.http.content-length == 17 + expect_close +} -run From gquintard at users.noreply.github.com Wed Aug 22 16:21:07 2018 From: gquintard at users.noreply.github.com (guillaume quintard) Date: Wed, 22 Aug 2018 16:21:07 +0000 (UTC) Subject: [master] f8e95527c Add release notes Message-ID: <20180822162107.26B52A4B71@lists.varnish-cache.org> commit f8e95527c0d3cf7f1bf6c23c21367bba20474c1a Author: Guillaume Quintard Date: Wed Aug 22 09:16:09 2018 -0700 Add release notes diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 175bee8a3..2561d7db6 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -806,7 +806,7 @@ VRT_r_obj_hits(VRT_CTX) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC); - return (ctx->req->is_hit ? ctx->req->objcore->hits : 0); + return (ctx->req->is_hit ? ctx->req->objcore->hits : 1); } VCL_BOOL diff --git a/doc/sphinx/whats-new/changes-6.1.rst b/doc/sphinx/whats-new/changes-6.1.rst index ee3644694..91d4b8491 100644 --- a/doc/sphinx/whats-new/changes-6.1.rst +++ b/doc/sphinx/whats-new/changes-6.1.rst @@ -10,4 +10,8 @@ Changes in Varnish 6.1 **XXX** +Varnish now won't rewrite the content-length header when responding to any HEAD +request, making it possible to cache HEAD requests independently from the GET +ones (peviously a HEAD request had to be a pass to avoid this rewriting). + *eof* From dridi at varni.sh Wed Aug 22 16:30:40 2018 From: dridi at varni.sh (Dridi Boukelmoune) Date: Wed, 22 Aug 2018 18:30:40 +0200 Subject: [master] f8e95527c Add release notes In-Reply-To: <20180822162107.26B52A4B71@lists.varnish-cache.org> References: <20180822162107.26B52A4B71@lists.varnish-cache.org> Message-ID: On Wed, Aug 22, 2018 at 6:21 PM, guillaume quintard wrote: > > commit f8e95527c0d3cf7f1bf6c23c21367bba20474c1a > Author: Guillaume Quintard > Date: Wed Aug 22 09:16:09 2018 -0700 > > Add release notes > > diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c > index 175bee8a3..2561d7db6 100644 > --- a/bin/varnishd/cache/cache_vrt_var.c > +++ b/bin/varnishd/cache/cache_vrt_var.c > @@ -806,7 +806,7 @@ VRT_r_obj_hits(VRT_CTX) > CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); > CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); > CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC); > - return (ctx->req->is_hit ? ctx->req->objcore->hits : 0); > + return (ctx->req->is_hit ? ctx->req->objcore->hits : 1); > } Smells like not release notes above. > VCL_BOOL > diff --git a/doc/sphinx/whats-new/changes-6.1.rst b/doc/sphinx/whats-new/changes-6.1.rst > index ee3644694..91d4b8491 100644 > --- a/doc/sphinx/whats-new/changes-6.1.rst > +++ b/doc/sphinx/whats-new/changes-6.1.rst > @@ -10,4 +10,8 @@ Changes in Varnish 6.1 > > **XXX** > > +Varnish now won't rewrite the content-length header when responding to any HEAD > +request, making it possible to cache HEAD requests independently from the GET > +ones (peviously a HEAD request had to be a pass to avoid this rewriting). > + > *eof* > _______________________________________________ > varnish-commit mailing list > varnish-commit at varnish-cache.org > https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit From guillaume at varnish-software.com Wed Aug 22 17:06:08 2018 From: guillaume at varnish-software.com (Guillaume Quintard) Date: Wed, 22 Aug 2018 17:06:08 +0000 (UTC) Subject: [master] b5aaa5426 Revert overcommitted change Message-ID: <20180822170609.13AA2A5C21@lists.varnish-cache.org> commit b5aaa5426aae16c2dbda9ac8f112351a193190a9 Author: Guillaume Quintard Date: Wed Aug 22 09:59:20 2018 -0700 Revert overcommitted change diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 2561d7db6..175bee8a3 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -806,7 +806,7 @@ VRT_r_obj_hits(VRT_CTX) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC); - return (ctx->req->is_hit ? ctx->req->objcore->hits : 1); + return (ctx->req->is_hit ? ctx->req->objcore->hits : 0); } VCL_BOOL From phk at FreeBSD.org Fri Aug 24 19:10:11 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 24 Aug 2018 19:10:11 +0000 (UTC) Subject: [master] 3f9ca3fcc Assign VMODS unique numbers, and make the count part of the VGC metadata Message-ID: <20180824191011.45F8D9B973@lists.varnish-cache.org> commit 3f9ca3fcc5ebb2ef3a1257e82a2a25c21464cb2e Author: Poul-Henning Kamp Date: Thu Aug 23 07:19:09 2018 +0000 Assign VMODS unique numbers, and make the count part of the VGC metadata diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py index 2b21aa0a2..4328c7072 100755 --- a/lib/libvcc/generate.py +++ b/lib/libvcc/generate.py @@ -666,6 +666,8 @@ struct VCL_conf { const char **srcname; const char **srcbody; + unsigned nvmod; + vcl_event_f *event_vcl; """) diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index 69a2db9c8..a7dfc98d3 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -424,6 +424,7 @@ EmitStruct(const struct vcc *tl) Fc(tl, 0, "\t.nsrc = VGC_NSRCS,\n"); Fc(tl, 0, "\t.srcname = srcname,\n"); Fc(tl, 0, "\t.srcbody = srcbody,\n"); + Fc(tl, 0, "\t.nvmod = %u,\n", tl->vmod_count); #define VCL_MET_MAC(l,u,t,b) \ Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); #include "tbl/vcl_returns.h" diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 01f2d92c0..befc15a94 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -252,7 +252,7 @@ struct vcc { const char *default_probe; unsigned unique; - + unsigned vmod_count; }; struct method { diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c index f34b0f3b1..a9cef1d71 100644 --- a/lib/libvcc/vcc_vmod.c +++ b/lib/libvcc/vcc_vmod.c @@ -336,6 +336,7 @@ vcc_ParseImport(struct vcc *tl) vcc_json_always(tl, msym); Fh(tl, 0, "\n/* --- BEGIN VMOD %.*s --- */\n\n", PF(mod)); + Fh(tl, 0, "#define VMOD_NUMBER_%.*s %u\n", PF(mod), tl->vmod_count++); Fh(tl, 0, "static struct vmod *VGC_vmod_%.*s;\n", PF(mod)); Fh(tl, 0, "static struct vmod_priv vmod_priv_%.*s;\n", PF(mod)); Fh(tl, 0, "\n%s\n", vmd->proto); From phk at FreeBSD.org Fri Aug 24 19:10:11 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 24 Aug 2018 19:10:11 +0000 (UTC) Subject: [master] 399bc4c1a Call VCL_Onboard whenever a req or bo gets a particular VCL for the first time. Message-ID: <20180824191011.646129B975@lists.varnish-cache.org> commit 399bc4c1ad3c32c8e8aeea756cd5ea512ac32603 Author: Poul-Henning Kamp Date: Thu Aug 23 07:47:55 2018 +0000 Call VCL_Onboard whenever a req or bo gets a particular VCL for the first time. diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 3533c665e..5527b588c 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -133,6 +133,7 @@ VBO_GetBusyObj(struct worker *wrk, const struct req *req) bo->director_req = req->director_hint; bo->vcl = req->vcl; VCL_Ref(bo->vcl); + VCL_Onboard(NULL, bo); bo->t_first = bo->t_prev = NAN; diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 1829804d6..516268c5b 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -164,6 +164,7 @@ ved_include(struct req *preq, const char *src, const char *host, AZ(req->vcl); req->vcl = preq->vcl; preq->vcl = NULL; + VCL_Onboard(req, NULL); req->req_step = R_STP_RECV; req->t_req = preq->t_req; diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 88c9f2cf7..3e12dfe45 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -388,6 +388,7 @@ void VCL_Poll(void); void VCL_Ref(struct vcl *); void VCL_Refresh(struct vcl **); void VCL_Rel(struct vcl **); +void VCL_Onboard(struct req *, struct busyobj *); const char *VCL_Return_Name(unsigned); const char *VCL_Method_Name(unsigned); void VCL_Bo2Ctx(struct vrt_ctx *, struct busyobj *); diff --git a/bin/varnishd/cache/cache_vcl_vrt.c b/bin/varnishd/cache/cache_vcl_vrt.c index 149d41d93..e377eb558 100644 --- a/bin/varnishd/cache/cache_vcl_vrt.c +++ b/bin/varnishd/cache/cache_vcl_vrt.c @@ -76,6 +76,16 @@ VCL_Method_Name(unsigned m) /*--------------------------------------------------------------------*/ +void +VCL_Onboard(struct req *req, struct busyobj *bo) +{ + + CHECK_OBJ_ORNULL(req, REQ_MAGIC); + CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); + assert(req != NULL || bo != NULL); + assert(req == NULL || bo == NULL); +} + void VCL_Refresh(struct vcl **vcc) { @@ -329,6 +339,7 @@ VRT_vcl_select(VRT_CTX, VCL_VCL vcl) vcl_get(&req->vcl, vcl); /* XXX: better logging */ VSLb(ctx->req->vsl, SLT_Debug, "Now using %s VCL", vcl->loaded_name); + VCL_Onboard(req, NULL); } struct vclref * diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index 650690950..b0dc5f472 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -330,6 +330,7 @@ http1_dissect(struct worker *wrk, struct req *req) VCL_Refresh(&wrk->vcl); req->vcl = wrk->vcl; wrk->vcl = NULL; + VCL_Onboard(req, NULL); HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); req->err_code = HTTP1_DissectRequest(req->htc, req->http); diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 41a689732..7713636c4 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -643,6 +643,7 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) VCL_Refresh(&wrk->vcl); req->vcl = wrk->vcl; wrk->vcl = NULL; + VCL_Onboard(req, NULL); req->acct.req_hdrbytes += h2->rxf_len; HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); From phk at FreeBSD.org Fri Aug 24 19:10:11 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 24 Aug 2018 19:10:11 +0000 (UTC) Subject: [master] 73fd9d730 Register the vmods unique (per-vcl) number Message-ID: <20180824191011.7D6119B978@lists.varnish-cache.org> commit 73fd9d730e4937eb0419702357544123b8ef8846 Author: Poul-Henning Kamp Date: Thu Aug 23 08:08:17 2018 +0000 Register the vmods unique (per-vcl) number diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c index ffd039ebc..25a119da4 100644 --- a/bin/varnishd/cache/cache_vrt_vmod.c +++ b/bin/varnishd/cache/cache_vrt_vmod.c @@ -53,6 +53,7 @@ struct vmod { int ref; char *nm; + unsigned nbr; char *path; char *backup; void *hdl; @@ -77,8 +78,8 @@ vmod_abi_mismatch(const struct vmod_data *d) } int -VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm, - const char *path, const char *file_id, const char *backup) +VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, unsigned nbr, void *ptr, int len, + const char *nm, const char *path, const char *file_id, const char *backup) { struct vmod *v; const struct vmod_data *d; @@ -138,6 +139,7 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm, return (1); } + v->nbr = nbr; v->funclen = d->func_len; v->funcs = d->func; v->abi = d->abi; diff --git a/include/vrt.h b/include/vrt.h index 4c41976fd..f49478fc2 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -58,6 +58,7 @@ * VRT_CollectStrands() added * VRT_STRANDS_string() removed from vrt.h (never implemented) * VRT_Healthy() changed prototype + * VRT_Vmod_Init signature changed * 7.0 (2018-03-15) * lots of stuff moved from cache.h to cache_varnishd.h * (ie: from "$Abi vrt" to "$Abi strict") @@ -471,7 +472,7 @@ void VRT_DelDirector(VCL_BACKEND *); int VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst); /* VMOD/Modules related */ -int VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, +int VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, unsigned nbr, void *ptr, int len, const char *nm, const char *path, const char *file_id, const char *backup); void VRT_Vmod_Fini(struct vmod **hdl); diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c index a9cef1d71..fd6a7acc6 100644 --- a/lib/libvcc/vcc_vmod.c +++ b/lib/libvcc/vcc_vmod.c @@ -305,6 +305,7 @@ vcc_ParseImport(struct vcc *tl) VSB_printf(ifp->ini, "\tif (VRT_Vmod_Init(ctx,\n"); VSB_printf(ifp->ini, "\t &VGC_vmod_%.*s,\n", PF(mod)); + VSB_printf(ifp->ini, "\t %u,\n", tl->vmod_count++); VSB_printf(ifp->ini, "\t &Vmod_%.*s_Func,\n", PF(mod)); VSB_printf(ifp->ini, "\t sizeof(Vmod_%.*s_Func),\n", PF(mod)); VSB_printf(ifp->ini, "\t \"%.*s\",\n", PF(mod)); @@ -336,7 +337,6 @@ vcc_ParseImport(struct vcc *tl) vcc_json_always(tl, msym); Fh(tl, 0, "\n/* --- BEGIN VMOD %.*s --- */\n\n", PF(mod)); - Fh(tl, 0, "#define VMOD_NUMBER_%.*s %u\n", PF(mod), tl->vmod_count++); Fh(tl, 0, "static struct vmod *VGC_vmod_%.*s;\n", PF(mod)); Fh(tl, 0, "static struct vmod_priv vmod_priv_%.*s;\n", PF(mod)); Fh(tl, 0, "\n%s\n", vmd->proto); From phk at FreeBSD.org Fri Aug 24 19:10:11 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Fri, 24 Aug 2018 19:10:11 +0000 (UTC) Subject: [master] 07123cfdc Retry on EAGAIN. Message-ID: <20180824191011.95B549B97E@lists.varnish-cache.org> commit 07123cfdca07bad6e0828131e24d9db23d0fe627 Author: Poul-Henning Kamp Date: Fri Aug 24 19:08:07 2018 +0000 Retry on EAGAIN. Submitted by: Frederic Lecaille diff --git a/bin/varnishtest/vtc_syslog.c b/bin/varnishtest/vtc_syslog.c index 4221b40eb..f91014c9a 100644 --- a/bin/varnishtest/vtc_syslog.c +++ b/bin/varnishtest/vtc_syslog.c @@ -306,7 +306,7 @@ syslog_rx(const struct syslog_srv *s, int lvl) ret = recv(s->sock, s->rxbuf, s->rxbuf_sz - 1, 0); if (ret < 0) { - if (errno == EINTR) + if (errno == EINTR || errno == EAGAIN) continue; vtc_fatal(s->vl, From dridi.boukelmoune at gmail.com Sat Aug 25 09:36:12 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Sat, 25 Aug 2018 09:36:12 +0000 (UTC) Subject: [master] c2a338293 Constify Message-ID: <20180825093613.2068DAE8B5@lists.varnish-cache.org> commit c2a3382933bc218175ded2bc435876a3a8d530ca Author: Dridi Boukelmoune Date: Sat Aug 25 11:30:15 2018 +0200 Constify diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 3e12dfe45..acd372b42 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -388,7 +388,7 @@ void VCL_Poll(void); void VCL_Ref(struct vcl *); void VCL_Refresh(struct vcl **); void VCL_Rel(struct vcl **); -void VCL_Onboard(struct req *, struct busyobj *); +void VCL_Onboard(const struct req *, const struct busyobj *); const char *VCL_Return_Name(unsigned); const char *VCL_Method_Name(unsigned); void VCL_Bo2Ctx(struct vrt_ctx *, struct busyobj *); diff --git a/bin/varnishd/cache/cache_vcl_vrt.c b/bin/varnishd/cache/cache_vcl_vrt.c index e377eb558..7e78d82b8 100644 --- a/bin/varnishd/cache/cache_vcl_vrt.c +++ b/bin/varnishd/cache/cache_vcl_vrt.c @@ -77,7 +77,7 @@ VCL_Method_Name(unsigned m) /*--------------------------------------------------------------------*/ void -VCL_Onboard(struct req *req, struct busyobj *bo) +VCL_Onboard(const struct req *req, const struct busyobj *bo) { CHECK_OBJ_ORNULL(req, REQ_MAGIC); From dridi.boukelmoune at gmail.com Mon Aug 27 08:44:08 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 27 Aug 2018 08:44:08 +0000 (UTC) Subject: [master] a419cec0f Whitespace OCD Message-ID: <20180827084408.6604865B56@lists.varnish-cache.org> commit a419cec0f1a74a20778b530594d831a03006eb64 Author: Dridi Boukelmoune Date: Mon Aug 27 10:43:33 2018 +0200 Whitespace OCD diff --git a/bin/varnishd/cache/cache_vcl_vrt.c b/bin/varnishd/cache/cache_vcl_vrt.c index 7e78d82b8..71e53a164 100644 --- a/bin/varnishd/cache/cache_vcl_vrt.c +++ b/bin/varnishd/cache/cache_vcl_vrt.c @@ -79,7 +79,7 @@ VCL_Method_Name(unsigned m) void VCL_Onboard(const struct req *req, const struct busyobj *bo) { - + CHECK_OBJ_ORNULL(req, REQ_MAGIC); CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); assert(req != NULL || bo != NULL); From dmatetelki at varnish-software.com Mon Aug 27 11:29:11 2018 From: dmatetelki at varnish-software.com (Denes Matetelki) Date: Mon, 27 Aug 2018 11:29:11 +0000 (UTC) Subject: [master] 785ecf0a8 Increasing libvarnishapi.so version from 1.0.6 to 2.0.0 Message-ID: <20180827112911.DDBCF91D0A@lists.varnish-cache.org> commit 785ecf0a8fd5f0d4864cf9091379f463f950d373 Author: Denes Matetelki Date: Thu Jun 21 13:22:56 2018 +0200 Increasing libvarnishapi.so version from 1.0.6 to 2.0.0 Fixes: libvarnishapi needs soname bump #2710 Should be backported to branches: 5.0, 5.1, 5.2, 6.0 diff --git a/lib/libvarnishapi/Makefile.am b/lib/libvarnishapi/Makefile.am index e679de3ac..5e13de019 100644 --- a/lib/libvarnishapi/Makefile.am +++ b/lib/libvarnishapi/Makefile.am @@ -9,7 +9,7 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libvarnishapi.la -libvarnishapi_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:6:0 +libvarnishapi_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2:0:0 libvarnishapi_la_SOURCES = \ vsl_api.h \ From noreply at github.com Mon Aug 27 11:29:12 2018 From: noreply at github.com (GitHub) Date: Mon, 27 Aug 2018 11:29:12 +0000 (UTC) Subject: [master] cd4188f89 Merge pull request #2718 from dmatetelki/libvarnishapi_soname_bump Message-ID: <20180827112912.1D77591D0D@lists.varnish-cache.org> commit cd4188f8954969963e111c1ce2efba78e9446573 Merge: a419cec0f 785ecf0a8 Author: Denes Matetelki Date: Mon Aug 27 13:28:23 2018 +0200 Merge pull request #2718 from dmatetelki/libvarnishapi_soname_bump Increasing libvarnishapi.so version from 1.0.6 to 2.0.0 From nils.goroll at uplex.de Mon Aug 27 12:09:13 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 27 Aug 2018 12:09:13 +0000 (UTC) Subject: [master] 8311f0bc8 fix obj.hits in vcl_hit Message-ID: <20180827120913.31D259376A@lists.varnish-cache.org> commit 8311f0bc8ea9e584b3fcb3447b341d18ead41135 Author: Nils Goroll Date: Mon Aug 27 14:06:19 2018 +0200 fix obj.hits in vcl_hit Fixes #2746 diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 175bee8a3..bfd0d80df 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -806,6 +806,8 @@ VRT_r_obj_hits(VRT_CTX) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC); + if (ctx->method == VCL_MET_HIT) + return (ctx->req->objcore->hits); return (ctx->req->is_hit ? ctx->req->objcore->hits : 0); } diff --git a/bin/varnishtest/tests/v00013.vtc b/bin/varnishtest/tests/v00013.vtc index 2772a2e18..52b81fc54 100644 --- a/bin/varnishtest/tests/v00013.vtc +++ b/bin/varnishtest/tests/v00013.vtc @@ -18,8 +18,14 @@ varnish v1 -vcl+backend { return (pass); } } + sub vcl_hit { + set req.http.hit-hits = obj.hits; + } sub vcl_deliver { - set resp.http.foo = obj.hits; + set resp.http.deliver-hits = obj.hits; + if (req.http.hit-hits) { + set resp.http.hit-hits = req.http.hit-hits; + } } } -start @@ -27,26 +33,31 @@ client c1 { txreq rxresp expect resp.status == 200 - expect resp.http.foo == 0 + expect resp.http.deliver-hits == 0 + expect resp.http.hit-hits == txreq rxresp expect resp.status == 200 - expect resp.http.foo == 1 + expect resp.http.deliver-hits == 1 + expect resp.http.hit-hits == 1 txreq -url /foo rxresp expect resp.status == 200 - expect resp.http.foo == 0 + expect resp.http.deliver-hits == 0 + expect resp.http.hit-hits == delay .1 txreq rxresp expect resp.status == 200 - expect resp.http.foo == 2 + expect resp.http.deliver-hits == 2 + expect resp.http.hit-hits == 2 txreq -url /pass rxresp expect resp.status == 200 - expect resp.http.foo == 0 + expect resp.http.deliver-hits == 0 + expect resp.http.hit-hits == } -run From nils.goroll at uplex.de Mon Aug 27 13:07:10 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Mon, 27 Aug 2018 13:07:10 +0000 (UTC) Subject: [master] fac3e589f improve documentation on backend timeout defaults Message-ID: <20180827130710.31DBF948A6@lists.varnish-cache.org> commit fac3e589f00cb7d60de57c1c8a32fda451ff5aa9 Author: Nils Goroll Date: Mon Aug 27 15:06:27 2018 +0200 improve documentation on backend timeout defaults diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index 913775778..d720dbc95 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -201,6 +201,8 @@ Example:: } +.. _ref_backend_def: + Backend definition ------------------ @@ -239,12 +241,18 @@ parameters. The following attributes are available: ``.connect_timeout`` Timeout for connections. + Default: :ref:`ref_param_connect_timeout` parameter. + ``.first_byte_timeout`` Timeout for first byte. + Default: :ref:`ref_param_first_byte_timeout` parameter. + ``.between_bytes_timeout`` Timeout between bytes. + Default: :ref:`ref_param_between_bytes_timeout` parameter. + ``.probe`` Attach a probe to the backend. See `Probes`_ diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 692a5888c..28044f145 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -585,6 +585,12 @@ bereq.connect_timeout Writable from: vcl_pipe, backend + Default: + + * :ref:`ref_backend_def` ``.connect_timeout`` attribute, which + defaults to + * :ref:`ref_param_connect_timeout` parameter. + The time in seconds to wait for a backend connection to be established. @@ -597,6 +603,12 @@ bereq.first_byte_timeout Writable from: backend + Default: + + * :ref:`ref_backend_def` ``.first_byte_timeout`` attribute, + which defaults to + * :ref:`ref_param_first_byte_timeout` parameter. + The time in seconds to wait getting the first byte back from the backend. Not available in pipe mode. @@ -609,6 +621,12 @@ bereq.between_bytes_timeout Writable from: backend + Default: + + * :ref:`ref_backend_def` ``.between_bytes_timeout`` backend + attribute, which defaults to + * :ref:`ref_param_between_bytes_timeout` parameter. + The time in seconds to wait between each received byte from the backend. Not available in pipe mode. From dridi.boukelmoune at gmail.com Mon Aug 27 18:20:15 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Mon, 27 Aug 2018 18:20:15 +0000 (UTC) Subject: [master] 4716028f3 Ensure VRT_priv_task doesn't get both req and bo Message-ID: <20180827182015.C79169C837@lists.varnish-cache.org> commit 4716028f3cbc61ee9e42ddc2ca1ffa1ca1733686 Author: Dridi Boukelmoune Date: Mon Aug 27 20:19:06 2018 +0200 Ensure VRT_priv_task doesn't get both req and bo diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 8d83f176c..09c18c54f 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -141,6 +141,7 @@ VRT_priv_task(VRT_CTX, const void *vmod_id) struct vrt_privs *vps; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + assert(ctx->req == NULL || ctx->bo == NULL); if (ctx->req) { CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); id = (uintptr_t)ctx->req; From phk at FreeBSD.org Tue Aug 28 06:43:16 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2018 06:43:16 +0000 (UTC) Subject: [master] f62c37514 Unify the H1/H2 reembark code. Message-ID: <20180828064316.B7A73AC875@lists.varnish-cache.org> commit f62c375144856ad90b667618570c4bcef414ce27 Author: Poul-Henning Kamp Date: Tue Aug 28 06:41:38 2018 +0000 Unify the H1/H2 reembark code. diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index deecc3434..a799a9f9a 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -50,6 +50,34 @@ #include "vsha256.h" #include "vtim.h" +/*-------------------------------------------------------------------- + * Reschedule a request from the waiting list + */ + +int +CNT_Reembark(struct worker *wrk, struct req *req) +{ + + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + + if (!DO_DEBUG(DBG_FAILRESCHED) && + !SES_Reschedule_Req(req, TASK_QUEUE_REQ)) + return (0); + + /* Couldn't schedule, ditch */ + wrk->stats->busy_wakeup--; + wrk->stats->busy_killed++; + VSLb(req->vsl, SLT_Error, "Fail to reschedule req from waiting list"); + + AN(req->ws->r); + WS_Release(req->ws, 0); + AN(req->hash_objhead); + (void)HSH_DerefObjHead(wrk, &req->hash_objhead); + AZ(req->hash_objhead); + return(-1); +} + /*-------------------------------------------------------------------- * Handle "Expect:" and "Connection:" on incoming request */ diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index acd372b42..de45a0fc0 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -335,6 +335,7 @@ enum req_fsm_nxt { }; enum req_fsm_nxt CNT_Request(struct worker *, struct req *); +int CNT_Reembark(struct worker *, struct req *); /* cache_session.c */ void SES_NewPool(struct pool *, unsigned pool_no); diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index b0dc5f472..ed3c9c8f4 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -47,7 +47,6 @@ static const char H1NEWREQ[] = "HTTP1::NewReq"; static const char H1PROC[] = "HTTP1::Proc"; -static const char H1BUSY[] = "HTTP1::Busy"; static const char H1CLEANUP[] = "HTTP1::Cleanup"; static void HTTP1_Session(struct worker *, struct req *); @@ -206,42 +205,19 @@ http1_req_cleanup(struct sess *sp, struct worker *wrk, struct req *req) * Clean up a req from waiting list which cannot complete */ -static void -http1_cleanup_waiting(struct worker *wrk, struct req *req, - enum sess_close reason) -{ - struct sess *sp; - - sp = req->sp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - AN(req->ws->r); - WS_Release(req->ws, 0); - AN(req->hash_objhead); - (void)HSH_DerefObjHead(wrk, &req->hash_objhead); - AZ(req->hash_objhead); - SES_Close(sp, reason); - AN(http1_req_cleanup(sp, wrk, req)); -} - static void v_matchproto_(vtr_reembark_f) http1_reembark(struct worker *wrk, struct req *req) { - struct sess *sp; - sp = req->sp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - - http1_setstate(sp, H1BUSY); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + assert(req->transport == &HTTP1_transport); - if (!DO_DEBUG(DBG_FAILRESCHED) && - !SES_Reschedule_Req(req, TASK_QUEUE_REQ)) + if (!CNT_Reembark(wrk, req)) return; - /* Couldn't schedule, ditch */ - wrk->stats->busy_wakeup--; - wrk->stats->busy_killed++; - VSLb(req->vsl, SLT_Error, "Fail to reschedule req from waiting list"); - http1_cleanup_waiting(wrk, req, SC_OVERLOAD); + SES_Close(req->sp, SC_OVERLOAD); + AN(http1_req_cleanup(req->sp, wrk, req)); } static int v_matchproto_(vtr_minimal_response_f) @@ -489,17 +465,6 @@ HTTP1_Session(struct worker *wrk, struct req *req) } req->req_step = R_STP_TRANSPORT; http1_setstate(sp, H1PROC); - } else if (st == H1BUSY) { - CHECK_OBJ_NOTNULL(req->transport, TRANSPORT_MAGIC); - /* - * Return from waitinglist. - * Check to see if the remote has left. - */ - if (VTCP_check_hup(sp->fd)) { - http1_cleanup_waiting(wrk, req, SC_REM_CLOSE); - return; - } - http1_setstate(sp, H1PROC); } else if (st == H1PROC) { req->task.func = http1_req; req->task.priv = req; diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h index 792fd985a..1c28f99ee 100644 --- a/bin/varnishd/http2/cache_http2.h +++ b/bin/varnishd/http2/cache_http2.h @@ -233,7 +233,6 @@ void h2_kill_req(struct worker *, const struct h2_sess *, int h2_rxframe(struct worker *, struct h2_sess *); h2_error h2_set_setting(struct h2_sess *, const uint8_t *); void h2_req_body(struct req*); -void h2_cleanup_waiting(struct worker *wrk, struct h2_req *r2); task_func_t h2_do_req; #ifdef TRANSPORT_MAGIC vtr_req_fail_f h2_req_fail; diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 7713636c4..644474309 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -1149,21 +1149,3 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2) } return (h2e ? 0 : 1); } - -void -h2_cleanup_waiting(struct worker *wrk, struct h2_req *r2) -{ - CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC); - CHECK_OBJ_NOTNULL(r2->req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(r2->h2sess, H2_SESS_MAGIC); - - AN(r2->req->ws->r); - WS_Release(r2->req->ws, 0); - AN(r2->req->hash_objhead); - (void)HSH_DerefObjHead(wrk, &r2->req->hash_objhead); - AZ(r2->req->hash_objhead); - assert(r2->state == H2_S_CLOS_REM); - AN(r2->scheduled); - r2->scheduled = 0; - r2->h2sess->do_sweep = 1; -} diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index 40a111754..8788dc45a 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -437,26 +437,22 @@ h2_new_session(struct worker *wrk, void *arg) static void v_matchproto_(vtr_reembark_f) h2_reembark(struct worker *wrk, struct req *req) { - struct sess *sp; struct h2_req *r2; - sp = req->sp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); + CHECK_OBJ_NOTNULL(req, REQ_MAGIC); assert(req->transport == &H2_transport); - if (!DO_DEBUG(DBG_FAILRESCHED) && - !SES_Reschedule_Req(req, TASK_QUEUE_STR)) + if (!CNT_Reembark(wrk, req)) return; - /* Couldn't schedule, ditch */ - wrk->stats->busy_wakeup--; - wrk->stats->busy_killed++; CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC); - VSLb(req->vsl, SLT_Error, "Fail to reschedule req from waiting list"); - h2_cleanup_waiting(wrk, r2); + assert(r2->state == H2_S_CLOS_REM); + AN(r2->scheduled); + r2->scheduled = 0; + r2->h2sess->do_sweep = 1; } - struct transport H2_transport = { .name = "H2", .magic = TRANSPORT_MAGIC, From dridi.boukelmoune at gmail.com Tue Aug 28 10:07:11 2018 From: dridi.boukelmoune at gmail.com (Dridi Boukelmoune) Date: Tue, 28 Aug 2018 10:07:11 +0000 (UTC) Subject: [master] 15a627c4c Whitespace OCD Message-ID: <20180828100712.069824D4A@lists.varnish-cache.org> commit 15a627c4cf306800c4dd5dd8854a27b6bf056c48 Author: Dridi Boukelmoune Date: Tue Aug 28 12:04:07 2018 +0200 Whitespace OCD diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 09c18c54f..b29f12047 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -139,6 +139,7 @@ VRT_priv_task(VRT_CTX, const void *vmod_id) { uintptr_t id; struct vrt_privs *vps; + struct vmod_priv *vp; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); assert(ctx->req == NULL || ctx->bo == NULL); @@ -155,8 +156,9 @@ VRT_priv_task(VRT_CTX, const void *vmod_id) id = (uintptr_t)cli_task_privs; CAST_OBJ_NOTNULL(vps, cli_task_privs, VRT_PRIVS_MAGIC); } - return (vrt_priv_dynamic(ctx->vcl, ctx->ws, - vps, id, (uintptr_t)vmod_id)); + + vp = vrt_priv_dynamic(ctx->vcl, ctx->ws, vps, id, (uintptr_t)vmod_id); + return (vp); } struct vmod_priv * From hermunn at varnish-software.com Tue Aug 28 14:25:14 2018 From: hermunn at varnish-software.com (Pål Hermunn Johansen) Date: Tue, 28 Aug 2018 14:25:14 +0000 (UTC) Subject: [6.0] 920d0d899 Changelog for 6.0.1 Message-ID: <20180828142514.C9A6860705@lists.varnish-cache.org> commit 920d0d8992de8ed9104775f2ba3f65f68b8121eb Author: P?l Hermunn Johansen Date: Fri Aug 24 17:13:52 2018 +0200 Changelog for 6.0.1 diff --git a/doc/changes.rst b/doc/changes.rst index 81b7d0a6f..d48a50b2f 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -31,6 +31,14 @@ release process. Varnish Cache 6.0.1 (ongoing) ================================ +* Added std.fnmatch() (2737_) +* The variable req.grace is back. (2705_) +* Importing the same VMOD multiple times is now allowed, if the file_id + is identical. + +.. _2705: https://github.com/varnishcache/varnish-cache/pull/2705 +.. _2737: https://github.com/varnishcache/varnish-cache/pull/2737 + varnishstat ----------- @@ -43,7 +51,7 @@ varnishstat * ``sess_fail_enomem`` * ``sess_fail_other`` - now break down the detailled reason for session accept failures, the + now break down the detailed reason for session accept failures, the sum of which continues to be counted in ``sess_fail``. VCL and bundled VMODs @@ -58,6 +66,81 @@ bundled tools for custom profile definitions to also contain a prefix to match the tag against. +* ``varnishtest``: syslog instances now have to start with a capital S. + +Fixed bugs which may influence VCL behavior +-------------------------------------------- + +* When an object is out of grace but in keep, the client context goes + straight to vcl_miss instead of vcl_hit. The documentation has been + updated accordingly. (2705_) + +Fixed bugs +---------- + +* Several H2 bugs (2285_, 2572_, 2623_, 2624_, 2679_, 2690_, 2693_) +* Make large integers work in VCL. (2603_) +* Print usage on unknown or missing arguments (2608_) +* Assert error in VPX_Send_Proxy() with proxy backends in pipe mode + (2613_) +* Holddown times for certain backend connection errors (2622_) +* Enforce Host requirement for HTTP/1.1 requests (2631_) +* Introduction of '-' CLI prefix allowed empty commands to sneak + through. (2647_) +* VUT apps can be stopped cleanly via vtc process -stop (2649_, 2650_) +* VUT apps fail gracefully when removing a PID file fails +* varnishd startup log should mention version (2661_) +* In curses mode, always filter in the counters necessary for the + header lines. (2678_) +* Assert error in ban_lurker_getfirst() (2681_) +* Missing command entries in varnishadm help menu (2682_) +* Handle string literal concatenation correctly (2685_) +* varnishtop -1 does not work as documented (2686_) +* Handle sigbus like sigsegv (2693_) +* Panic on return (retry) of a conditional fetch (2700_) +* Wrong turn at cache/cache_backend_probe.c:255: Unknown family + (2702_, 2726_) +* VCL failure causes TASK_PRIV reference on reset workspace (2706_) +* Accurate ban statistics except for a few remaining corner cases + (2716_) +* Assert error in vca_make_session() (2719_) +* Assert error in vca_tcp_opt_set() (2722_) +* VCL compiling error on parenthesis (2727_) +* Assert error in HTC_RxPipeline() (2731_) + +.. _2285: https://github.com/varnishcache/varnish-cache/issues/2285 +.. _2572: https://github.com/varnishcache/varnish-cache/issues/2572 +.. _2603: https://github.com/varnishcache/varnish-cache/issues/2603 +.. _2608: https://github.com/varnishcache/varnish-cache/issues/2608 +.. _2613: https://github.com/varnishcache/varnish-cache/issues/2613 +.. _2622: https://github.com/varnishcache/varnish-cache/issues/2622 +.. _2623: https://github.com/varnishcache/varnish-cache/issues/2623 +.. _2624: https://github.com/varnishcache/varnish-cache/issues/2624 +.. _2631: https://github.com/varnishcache/varnish-cache/issues/2631 +.. _2647: https://github.com/varnishcache/varnish-cache/issues/2647 +.. _2649: https://github.com/varnishcache/varnish-cache/issues/2649 +.. _2650: https://github.com/varnishcache/varnish-cache/pull/2650 +.. _2651: https://github.com/varnishcache/varnish-cache/pull/2651 +.. _2661: https://github.com/varnishcache/varnish-cache/issues/2661 +.. _2678: https://github.com/varnishcache/varnish-cache/issues/2678 +.. _2679: https://github.com/varnishcache/varnish-cache/issues/2679 +.. _2681: https://github.com/varnishcache/varnish-cache/issues/2681 +.. _2682: https://github.com/varnishcache/varnish-cache/issues/2682 +.. _2685: https://github.com/varnishcache/varnish-cache/issues/2685 +.. _2686: https://github.com/varnishcache/varnish-cache/issues/2686 +.. _2690: https://github.com/varnishcache/varnish-cache/issues/2690 +.. _2693: https://github.com/varnishcache/varnish-cache/issues/2693 +.. _2695: https://github.com/varnishcache/varnish-cache/issues/2695 +.. _2700: https://github.com/varnishcache/varnish-cache/issues/2700 +.. _2702: https://github.com/varnishcache/varnish-cache/issues/2702 +.. _2706: https://github.com/varnishcache/varnish-cache/issues/2706 +.. _2716: https://github.com/varnishcache/varnish-cache/issues/2716 +.. _2719: https://github.com/varnishcache/varnish-cache/issues/2719 +.. _2722: https://github.com/varnishcache/varnish-cache/issues/2722 +.. _2726: https://github.com/varnishcache/varnish-cache/pull/2726 +.. _2727: https://github.com/varnishcache/varnish-cache/issues/2727 +.. _2731: https://github.com/varnishcache/varnish-cache/issues/2731 + ================================ Varnish Cache 6.0.0 (2018-03-15) ================================ From nils.goroll at uplex.de Tue Aug 28 15:45:11 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 28 Aug 2018 15:45:11 +0000 (UTC) Subject: [master] 43b981048 use references which work both for html and man pages Message-ID: <20180828154511.DD82161D8C@lists.varnish-cache.org> commit 43b981048816948b5fbd17db4f54486b055991c2 Author: Nils Goroll Date: Tue Aug 28 17:39:06 2018 +0200 use references which work both for html and man pages diff --git a/doc/sphinx/reference/vcl.rst b/doc/sphinx/reference/vcl.rst index d720dbc95..7aa434da6 100644 --- a/doc/sphinx/reference/vcl.rst +++ b/doc/sphinx/reference/vcl.rst @@ -200,8 +200,7 @@ Example:: */ } - -.. _ref_backend_def: +.. _backend_definition: Backend definition ------------------ @@ -241,17 +240,17 @@ parameters. The following attributes are available: ``.connect_timeout`` Timeout for connections. - Default: :ref:`ref_param_connect_timeout` parameter. + Default: ``connect_timeout`` parameter, see :ref:`varnishd(1)` ``.first_byte_timeout`` Timeout for first byte. - Default: :ref:`ref_param_first_byte_timeout` parameter. + Default: ``first_byte_timeout`` parameter, see :ref:`varnishd(1)` ``.between_bytes_timeout`` Timeout between bytes. - Default: :ref:`ref_param_between_bytes_timeout` parameter. + Default: ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)` ``.probe`` Attach a probe to the backend. See `Probes`_ diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index 28044f145..b54c654e4 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -587,9 +587,9 @@ bereq.connect_timeout Default: - * :ref:`ref_backend_def` ``.connect_timeout`` attribute, which - defaults to - * :ref:`ref_param_connect_timeout` parameter. + * ``.connect_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + * ``connect_timeout`` parameter, see :ref:`varnishd(1)` The time in seconds to wait for a backend connection to be established. @@ -605,9 +605,9 @@ bereq.first_byte_timeout Default: - * :ref:`ref_backend_def` ``.first_byte_timeout`` attribute, - which defaults to - * :ref:`ref_param_first_byte_timeout` parameter. + * ``.first_byte_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + * ``first_byte_timeout`` parameter, see :ref:`varnishd(1)` The time in seconds to wait getting the first byte back from the backend. Not available in pipe mode. @@ -623,9 +623,9 @@ bereq.between_bytes_timeout Default: - * :ref:`ref_backend_def` ``.between_bytes_timeout`` backend - attribute, which defaults to - * :ref:`ref_param_between_bytes_timeout` parameter. + * ``.between_bytes_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + * ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)` The time in seconds to wait between each received byte from the backend. Not available in pipe mode. From nils.goroll at uplex.de Tue Aug 28 20:16:08 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Tue, 28 Aug 2018 20:16:08 +0000 (UTC) Subject: [master] c0a4ee41c in vmod destructors, tolerate failed object initializations Message-ID: <20180828201608.AD5A36E767@lists.varnish-cache.org> commit c0a4ee41ca968df7fd0efa64d794c7629d75c233 Author: Nils Goroll Date: Tue Aug 28 22:15:14 2018 +0200 in vmod destructors, tolerate failed object initializations works around #2297 diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c index e6d3e7226..02ac28186 100644 --- a/lib/libvmod_directors/fall_back.c +++ b/lib/libvmod_directors/fall_back.c @@ -124,6 +124,10 @@ vmod_fallback__fini(struct vmod_directors_fallback **fbp) { struct vmod_directors_fallback *fb; + // XXX 2297 + if (*fbp == NULL) + return; + TAKE_OBJ_NOTNULL(fb, fbp, VMOD_DIRECTORS_FALLBACK_MAGIC); VRT_DelDirector(&fb->vd->dir); } diff --git a/lib/libvmod_directors/hash.c b/lib/libvmod_directors/hash.c index a82e19fe3..010aaeaa2 100644 --- a/lib/libvmod_directors/hash.c +++ b/lib/libvmod_directors/hash.c @@ -83,6 +83,10 @@ vmod_hash__fini(struct vmod_directors_hash **rrp) { struct vmod_directors_hash *rr; + // XXX 2297 + if (*rrp == NULL) + return; + TAKE_OBJ_NOTNULL(rr, rrp, VMOD_DIRECTORS_HASH_MAGIC); VRT_DelDirector(&rr->vd->dir); } diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c index 430f3e594..567315193 100644 --- a/lib/libvmod_directors/random.c +++ b/lib/libvmod_directors/random.c @@ -111,6 +111,10 @@ vmod_random__fini(struct vmod_directors_random **rrp) { struct vmod_directors_random *rr; + // XXX 2297 + if (*rrp == NULL) + return; + TAKE_OBJ_NOTNULL(rr, rrp, VMOD_DIRECTORS_RANDOM_MAGIC); VRT_DelDirector(&rr->vd->dir); } diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c index af2aec3b8..bd50bfedd 100644 --- a/lib/libvmod_directors/round_robin.c +++ b/lib/libvmod_directors/round_robin.c @@ -119,6 +119,10 @@ vmod_round_robin__fini(struct vmod_directors_round_robin **rrp) { struct vmod_directors_round_robin *rr; + // XXX 2297 + if (*rrp == NULL) + return; + TAKE_OBJ_NOTNULL(rr, rrp, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC); VRT_DelDirector(&rr->vd->dir); } diff --git a/lib/libvmod_directors/vmod_shard.c b/lib/libvmod_directors/vmod_shard.c index 558675335..1d366195c 100644 --- a/lib/libvmod_directors/vmod_shard.c +++ b/lib/libvmod_directors/vmod_shard.c @@ -270,6 +270,10 @@ vmod_shard__fini(struct vmod_directors_shard **vshardp) { struct vmod_directors_shard *vshard; + // XXX 2297 + if (*vshardp == NULL) + return; + TAKE_OBJ_NOTNULL(vshard, vshardp, VMOD_SHARD_SHARD_MAGIC); VRT_DelDirector(&vshard->dir); FREE_OBJ(vshard); @@ -785,8 +789,10 @@ vmod_shard_param__fini(struct vmod_directors_shard_param **pp) { struct vmod_directors_shard_param *p; + // XXX 2297 if (*pp == NULL) return; + TAKE_OBJ_NOTNULL(p, pp, VMOD_SHARD_SHARD_PARAM_MAGIC); FREE_OBJ(p); } From phk at FreeBSD.org Tue Aug 28 20:28:08 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2018 20:28:08 +0000 (UTC) Subject: [master] 59367a6ce Always reschedule requests from the waiting list. Message-ID: <20180828202808.B41A16ECA1@lists.varnish-cache.org> commit 59367a6ce989f3b3cf237a135ade4a94641fbfc5 Author: Poul-Henning Kamp Date: Tue Aug 28 20:27:37 2018 +0000 Always reschedule requests from the waiting list. Previously we used various heuristics (test TCP connection) to avoid the reschedule if the req was abandonned while on the waiting list. We also subjected the rescheduling to pool-queue limits like any new request. This was all safe because we knew we could clean up the request state cheaply, even if it was somewhat cumbersome. Now vmods can have per-task PRIV's and we have no idea what it will cost us (stack, time, etc) to clean them up, so we cannot burden J.Random Request who happens to rush the waiting list with the burden. Fix this by always rescheduling, not subject to pool-queue limits, and eliminate all the special-casing for exceeded limits, including the debug feature to force a rescheduling failure and two tests exercising it. As a side effect of this, requests on the waiting list gets a "business class upgrade" over newly arriving requests when there are no worker threads available. Given that these requests arrived earlier, and we already performed work on them, this seems only fair. Forced to pay proper attention by: slink diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index c5c5cb9b0..e8dc2f3de 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -217,10 +217,17 @@ struct pool_task { * tasks are taken off the queues in this order * * prios up to TASK_QUEUE_RESERVE are run from the reserve + * + * TASK_QUEUE_{REQ|STR} are new req's (H1/H2), and subject to queue limit. + * + * TASK_QUEUE_RUSH is req's returning from waiting list, they are + * not subject to TASK_QUEUE_CLIENT because we cannot safely clean + * them up if scheduling them fails. */ enum task_prio { TASK_QUEUE_BO, #define TASK_QUEUE_RESERVE TASK_QUEUE_BO + TASK_QUEUE_RUSH, TASK_QUEUE_REQ, TASK_QUEUE_STR, TASK_QUEUE_VCA, diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 3fbbc702d..c3b652bbe 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -76,6 +76,7 @@ static struct objhead *private_oh; static void hsh_rush1(const struct worker *, struct objhead *, struct rush *, int); static void hsh_rush2(struct worker *, struct rush *); +static int HSH_DerefObjHead(struct worker *wrk, struct objhead **poh); /*---------------------------------------------------------------------*/ @@ -591,8 +592,18 @@ hsh_rush2(struct worker *wrk, struct rush *r) CHECK_OBJ_NOTNULL(req, REQ_MAGIC); VTAILQ_REMOVE(&r->reqs, req, w_list); DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list"); - AN(req->transport->reembark); - req->transport->reembark(wrk, req); + if (req->transport->reembark != NULL) { + // For ESI includes + req->transport->reembark(wrk, req); + } else { + /* + * We ignore the queue limits which apply to new + * requests because if we fail to reschedule there + * may be vmod_privs to cleanup and we need a proper + * workerthread for that. + */ + AZ(Pool_Task(req->sp->pool, &req->task, TASK_QUEUE_RUSH)); + } } } @@ -939,7 +950,7 @@ HSH_DerefObjCore(struct worker *wrk, struct objcore **ocp, int rushmax) return (0); } -int +static int HSH_DerefObjHead(struct worker *wrk, struct objhead **poh) { struct objhead *oh; diff --git a/bin/varnishd/cache/cache_objhead.h b/bin/varnishd/cache/cache_objhead.h index 6bcfbd9b9..6bcb7b301 100644 --- a/bin/varnishd/cache/cache_objhead.h +++ b/bin/varnishd/cache/cache_objhead.h @@ -63,7 +63,6 @@ int HSH_Snipe(const struct worker *, struct objcore *); struct boc *HSH_RefBoc(const struct objcore *); void HSH_DerefBoc(struct worker *wrk, struct objcore *); void HSH_DeleteObjHead(const struct worker *, struct objhead *); -int HSH_DerefObjHead(struct worker *, struct objhead **); int HSH_DerefObjCore(struct worker *, struct objcore **, int rushmax); #define HSH_RUSH_POLICY -1 diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index a799a9f9a..deecc3434 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -50,34 +50,6 @@ #include "vsha256.h" #include "vtim.h" -/*-------------------------------------------------------------------- - * Reschedule a request from the waiting list - */ - -int -CNT_Reembark(struct worker *wrk, struct req *req) -{ - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - - if (!DO_DEBUG(DBG_FAILRESCHED) && - !SES_Reschedule_Req(req, TASK_QUEUE_REQ)) - return (0); - - /* Couldn't schedule, ditch */ - wrk->stats->busy_wakeup--; - wrk->stats->busy_killed++; - VSLb(req->vsl, SLT_Error, "Fail to reschedule req from waiting list"); - - AN(req->ws->r); - WS_Release(req->ws, 0); - AN(req->hash_objhead); - (void)HSH_DerefObjHead(wrk, &req->hash_objhead); - AZ(req->hash_objhead); - return(-1); -} - /*-------------------------------------------------------------------- * Handle "Expect:" and "Connection:" on incoming request */ diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 0500bcef2..20ada52e3 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -376,30 +376,6 @@ SES_New(struct pool *pp) return (sp); } -/*-------------------------------------------------------------------- - * Reschedule a request on a work-thread from its sessions pool - * - * This is used to reschedule requests waiting on busy objects - */ - -int -SES_Reschedule_Req(struct req *req, enum task_prio prio) -{ - struct sess *sp; - struct pool *pp; - - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - sp = req->sp; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); - pp = sp->pool; - CHECK_OBJ_NOTNULL(pp, POOL_MAGIC); - AN(TASK_QUEUE_CLIENT(prio)); - - AN(req->task.func); - - return (Pool_Task(pp, &req->task, prio)); -} - /*-------------------------------------------------------------------- * Handle a session (from waiter) */ diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index de45a0fc0..52a7e9622 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -335,7 +335,6 @@ enum req_fsm_nxt { }; enum req_fsm_nxt CNT_Request(struct worker *, struct req *); -int CNT_Reembark(struct worker *, struct req *); /* cache_session.c */ void SES_NewPool(struct pool *, unsigned pool_no); @@ -343,7 +342,6 @@ void SES_DestroyPool(struct pool *); void SES_Wait(struct sess *, const struct transport *); void SES_Ref(struct sess *sp); void SES_Rel(struct sess *sp); -int SES_Reschedule_Req(struct req *, enum task_prio); const char * HTC_Status(enum htc_status_e); void HTC_RxInit(struct http_conn *htc, struct ws *ws); diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index ed3c9c8f4..30bd3b894 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -201,25 +201,6 @@ http1_req_cleanup(struct sess *sp, struct worker *wrk, struct req *req) return (0); } -/*---------------------------------------------------------------------- - * Clean up a req from waiting list which cannot complete - */ - -static void v_matchproto_(vtr_reembark_f) -http1_reembark(struct worker *wrk, struct req *req) -{ - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - assert(req->transport == &HTTP1_transport); - - if (!CNT_Reembark(wrk, req)) - return; - - SES_Close(req->sp, SC_OVERLOAD); - AN(http1_req_cleanup(req->sp, wrk, req)); -} - static int v_matchproto_(vtr_minimal_response_f) http1_minimal_response(struct req *req, uint16_t status) { @@ -263,7 +244,6 @@ struct transport HTTP1_transport = { .deliver = V1D_Deliver, .minimal_response = http1_minimal_response, .new_session = http1_new_session, - .reembark = http1_reembark, .req_body = http1_req_body, .req_fail = http1_req_fail, .req_panic = http1_req_panic, diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index 8788dc45a..5985fe472 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -434,32 +434,12 @@ h2_new_session(struct worker *wrk, void *arg) h2_del_sess(wrk, h2, SC_RX_JUNK); } -static void v_matchproto_(vtr_reembark_f) -h2_reembark(struct worker *wrk, struct req *req) -{ - struct h2_req *r2; - - CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); - CHECK_OBJ_NOTNULL(req, REQ_MAGIC); - assert(req->transport == &H2_transport); - - if (!CNT_Reembark(wrk, req)) - return; - - CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC); - assert(r2->state == H2_S_CLOS_REM); - AN(r2->scheduled); - r2->scheduled = 0; - r2->h2sess->do_sweep = 1; -} - struct transport H2_transport = { .name = "H2", .magic = TRANSPORT_MAGIC, .deliver = h2_deliver, .minimal_response = h2_minimal_response, .new_session = h2_new_session, - .reembark = h2_reembark, .req_body = h2_req_body, .req_fail = h2_req_fail, .sess_panic = h2_sess_panic, diff --git a/bin/varnishtest/tests/c00013.vtc b/bin/varnishtest/tests/c00013.vtc index 1fcccac4a..ef4cc76f8 100644 --- a/bin/varnishtest/tests/c00013.vtc +++ b/bin/varnishtest/tests/c00013.vtc @@ -50,60 +50,3 @@ varnish v1 -vsl_catchup varnish v1 -expect busy_sleep >= 1 varnish v1 -expect busy_wakeup >= 1 varnish v1 -stop - -################################################## -# Now try again where getting a thread fails - -barrier b3 cond 2 -barrier b4 cond 2 - -server s3 { - rxreq - expect req.url == "/foo" - send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" - delay .2 - barrier b3 sync - delay .2 - send "line1\n" - delay .2 - barrier b4 sync - send "line2\n" -} -start - -varnish v3 -vcl+backend { - sub vcl_backend_fetch { - set bereq.backend = s3; - } - sub vcl_backend_response { - set beresp.do_stream = false; - } -} -start - -varnish v3 -cliok "param.set debug +failresched" - -varnish v3 -cliok "param.set debug +syncvsl" - -client c3 -connect ${v3_sock} { - txreq -url "/foo" -hdr "client: c3" - rxresp - expect resp.status == 200 - expect resp.bodylen == 12 - expect resp.http.x-varnish == "1001" -} -start - -barrier b3 sync - -client c4 -connect ${v3_sock} { - txreq -url "/foo" -hdr "client: c4" - delay .2 - barrier b4 sync - expect_close -} -run - -client c3 -wait - -varnish v1 -vsl_catchup -varnish v3 -expect busy_sleep >= 1 -varnish v3 -expect busy_wakeup == 0 -varnish v3 -expect busy_killed == 1 -varnish v3 -expect sc_overload == 1 diff --git a/bin/varnishtest/tests/r02563.vtc b/bin/varnishtest/tests/r02563.vtc deleted file mode 100644 index bfe3514b9..000000000 --- a/bin/varnishtest/tests/r02563.vtc +++ /dev/null @@ -1,64 +0,0 @@ -varnishtest "#2563: Panic after reembark failure" - -barrier b1 cond 2 -barrier b2 cond 2 - -server s1 { - rxreq - expect req.url == "/foo" - expect req.http.client == "c1" - send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" - delay .2 - barrier b1 sync - delay .2 - send "line1\n" - delay .2 - barrier b2 sync - send "line2\n" -} -start - -varnish v1 -vcl+backend { - sub vcl_backend_response { - set beresp.do_stream = false; - } -} -start - -varnish v1 -cliok "param.set feature +http2" -varnish v1 -cliok "param.set debug +failresched" -varnish v1 -cliok "param.set debug +waitinglist" -varnish v1 -cliok "param.set debug +syncvsl" - -client c1 { - txreq -url "/foo" -hdr "client: c1" - rxresp - expect resp.status == 200 - expect resp.bodylen == 12 - expect resp.http.x-varnish == "1001" -} -start - -barrier b1 sync - -client c2 { - stream 1 { - txreq -url "/foo" - delay .2 - barrier b2 sync - rxrst - expect rst.err == REFUSED_STREAM - } -start - - stream 3 { - delay 1 - txreq -url "/foo" - rxresp - } -run - - stream 1 -wait -} -run - -client c1 -wait - -varnish v1 -vsl_catchup -varnish v1 -expect busy_sleep >= 1 -varnish v1 -expect busy_wakeup == 0 -varnish v1 -expect busy_killed == 1 diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h index b451f3332..4ac3ef60f 100644 --- a/include/tbl/debug_bits.h +++ b/include/tbl/debug_bits.h @@ -50,7 +50,6 @@ DEBUG_BIT(H2_NOCHECK, h2_nocheck, "Disable various H2 checks") DEBUG_BIT(VMOD_SO_KEEP, vmod_so_keep, "Keep copied VMOD libraries") DEBUG_BIT(PROCESSORS, processors, "Fetch/Deliver processors") DEBUG_BIT(PROTOCOL, protocol, "Protocol debugging") -DEBUG_BIT(FAILRESCHED, failresched, "Fail from waiting list") #undef DEBUG_BIT /*lint -restore */ From fgsch at lodoss.net Tue Aug 28 20:55:06 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Tue, 28 Aug 2018 20:55:06 +0000 (UTC) Subject: [master] 2aa60d4e5 Whitespace Message-ID: <20180828205506.D9161908C9@lists.varnish-cache.org> commit 2aa60d4e5a74ea702199dbbcea95951c4b20a770 Author: Federico G. Schwindt Date: Tue Aug 28 21:52:03 2018 +0100 Whitespace diff --git a/bin/varnishtest/huffman_gen.py b/bin/varnishtest/huffman_gen.py index 00ff16fe6..8da37b2ee 100755 --- a/bin/varnishtest/huffman_gen.py +++ b/bin/varnishtest/huffman_gen.py @@ -12,7 +12,7 @@ if len(sys.argv) != 2: class sym: def __init__(self, bigval, bigvall, chr = 0, esc = None): - self.vall = bigvall % 8 if bigvall % 8 else 8 + self.vall = bigvall % 8 if bigvall % 8 else 8 self.val = bigval & ((1 << self.vall) - 1) self.pfx = (bigval >> self.vall)# & 0xff self.chr = chr From fgsch at lodoss.net Tue Aug 28 20:55:06 2018 From: fgsch at lodoss.net (Federico G. Schwindt) Date: Tue, 28 Aug 2018 20:55:06 +0000 (UTC) Subject: [master] ccf616762 Formatting Message-ID: <20180828205506.EBD58908CC@lists.varnish-cache.org> commit ccf616762078a955c2d6e60641ba5cce58f3c193 Author: Federico G. Schwindt Date: Tue Aug 28 21:52:28 2018 +0100 Formatting diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index b54c654e4..054cf2ff4 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -585,11 +585,9 @@ bereq.connect_timeout Writable from: vcl_pipe, backend - Default: - - * ``.connect_timeout`` attribute from the - :ref:`backend_definition`, which defaults to the - * ``connect_timeout`` parameter, see :ref:`varnishd(1)` + Default: ``.connect_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + ``connect_timeout`` parameter, see :ref:`varnishd(1)` The time in seconds to wait for a backend connection to be established. @@ -603,11 +601,9 @@ bereq.first_byte_timeout Writable from: backend - Default: - - * ``.first_byte_timeout`` attribute from the - :ref:`backend_definition`, which defaults to the - * ``first_byte_timeout`` parameter, see :ref:`varnishd(1)` + Default: ``.first_byte_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + ``first_byte_timeout`` parameter, see :ref:`varnishd(1)` The time in seconds to wait getting the first byte back from the backend. Not available in pipe mode. @@ -621,11 +617,9 @@ bereq.between_bytes_timeout Writable from: backend - Default: - - * ``.between_bytes_timeout`` attribute from the - :ref:`backend_definition`, which defaults to the - * ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)` + Default: ``.between_bytes_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)` The time in seconds to wait between each received byte from the backend. Not available in pipe mode. From phk at FreeBSD.org Tue Aug 28 20:55:07 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2018 20:55:07 +0000 (UTC) Subject: [master] 0068b31aa Collect and make explicit where we enter and leave "tasks" for the purpose of VRT_priv_task() Message-ID: <20180828205507.13401908CF@lists.varnish-cache.org> commit 0068b31aa70140f729a729acdfa1dbb7b2678a50 Author: Poul-Henning Kamp Date: Tue Aug 28 20:52:13 2018 +0000 Collect and make explicit where we enter and leave "tasks" for the purpose of VRT_priv_task() diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index 5527b588c..e27431042 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -133,14 +133,11 @@ VBO_GetBusyObj(struct worker *wrk, const struct req *req) bo->director_req = req->director_hint; bo->vcl = req->vcl; VCL_Ref(bo->vcl); - VCL_Onboard(NULL, bo); bo->t_first = bo->t_prev = NAN; memcpy(bo->digest, req->digest, sizeof bo->digest); - VRTPRIV_init(bo->privs); - return (bo); } @@ -156,8 +153,7 @@ VBO_ReleaseBusyObj(struct worker *wrk, struct busyobj **pbo) AZ(bo->htc); AZ(bo->stale_oc); - VRTPRIV_dynamic_kill(bo->privs, (uintptr_t)bo); - assert(VTAILQ_EMPTY(&bo->privs->privs)); + AZ(bo->privs->magic); VSLb(bo->vsl, SLT_BereqAcct, "%ju %ju %ju %ju %ju %ju", (uintmax_t)bo->acct.bereq_hdrbytes, diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 516268c5b..1e238d854 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -164,7 +164,6 @@ ved_include(struct req *preq, const char *src, const char *host, AZ(req->vcl); req->vcl = preq->vcl; preq->vcl = NULL; - VCL_Onboard(req, NULL); req->req_step = R_STP_RECV; req->t_req = preq->t_req; @@ -198,8 +197,6 @@ ved_include(struct req *preq, const char *src, const char *host, AZ(req->wrk); } - VRTPRIV_dynamic_kill(req->privs, (uintptr_t)req); - AZ(preq->vcl); preq->vcl = req->vcl; req->vcl = NULL; diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 0f81e544e..57583239a 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -924,6 +924,7 @@ vbf_fetch_thread(struct worker *wrk, void *priv) } #endif + VCL_TaskEnter(bo->vcl, bo->privs); while (stp != F_STP_DONE) { CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); assert(bo->fetch_objcore->boc->refcount >= 1); @@ -944,6 +945,7 @@ vbf_fetch_thread(struct worker *wrk, void *priv) assert(bo->director_state == DIR_S_NULL); + VCL_TaskLeave(bo->vcl, bo->privs); http_Teardown(bo->bereq); http_Teardown(bo->beresp); diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c index d741441ca..036056740 100644 --- a/bin/varnishd/cache/cache_req.c +++ b/bin/varnishd/cache/cache_req.c @@ -149,8 +149,6 @@ Req_New(const struct worker *wrk, struct sess *sp) req->t_prev = NAN; req->t_req = NAN; - VRTPRIV_init(req->privs); - return (req); } @@ -181,14 +179,6 @@ Req_Release(struct req *req) MPL_Free(pp->mpl_req, req); } -static void -req_finalize(struct req *req) -{ - VRTPRIV_dynamic_kill(req->privs, (uintptr_t)req); - VRTPRIV_dynamic_kill(req->privs, (uintptr_t)&req->top); - assert(VTAILQ_EMPTY(&req->privs->privs)); -} - /*---------------------------------------------------------------------- * TODO: * - check for code duplication with cnt_recv_prep @@ -198,7 +188,8 @@ req_finalize(struct req *req) void Req_Rollback(struct req *req) { - req_finalize(req); + VCL_TaskLeave(req->vcl, req->privs); + VCL_TaskEnter(req->vcl, req->privs); HTTP_Copy(req->http, req->http0); WS_Reset(req->ws, req->ws_req); } @@ -220,6 +211,7 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) req->restarts = 0; AZ(req->esi_level); + AZ(req->privs->magic); assert(req->top == req); if (req->vcl != NULL) { @@ -229,8 +221,6 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) req->vcl = NULL; } - req_finalize(req); - /* Charge and log byte counters */ if (req->vsl->wid) { Req_AcctLogCharge(wrk->stats, req); diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c index deecc3434..dcf6e9df0 100644 --- a/bin/varnishd/cache/cache_req_fsm.c +++ b/bin/varnishd/cache/cache_req_fsm.c @@ -1022,6 +1022,7 @@ CNT_Request(struct worker *wrk, struct req *req) CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); + AN(req->vcl); /* * Possible entrance states @@ -1036,6 +1037,8 @@ CNT_Request(struct worker *wrk, struct req *req) /* wrk can have changed for restarts */ req->vfc->wrk = req->wrk = wrk; wrk->vsl = req->vsl; + if (req->req_step != R_STP_LOOKUP) + VCL_TaskEnter(req->vcl, req->privs); for (nxt = REQ_FSM_MORE; nxt == REQ_FSM_MORE; ) { /* * This is a good place to be paranoid about the various @@ -1060,6 +1063,7 @@ CNT_Request(struct worker *wrk, struct req *req) } wrk->vsl = NULL; if (nxt == REQ_FSM_DONE) { + VCL_TaskLeave(req->vcl, req->privs); AN(req->vsl->wid); VRB_Free(req); req->wrk = NULL; diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 52a7e9622..154a6796b 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -387,7 +387,8 @@ void VCL_Poll(void); void VCL_Ref(struct vcl *); void VCL_Refresh(struct vcl **); void VCL_Rel(struct vcl **); -void VCL_Onboard(const struct req *, const struct busyobj *); +void VCL_TaskEnter(struct vcl *, struct vrt_privs *); +void VCL_TaskLeave(struct vcl *, struct vrt_privs *); const char *VCL_Return_Name(unsigned); const char *VCL_Method_Name(unsigned); void VCL_Bo2Ctx(struct vrt_ctx *, struct busyobj *); diff --git a/bin/varnishd/cache/cache_vcl_vrt.c b/bin/varnishd/cache/cache_vcl_vrt.c index 71e53a164..06b006b52 100644 --- a/bin/varnishd/cache/cache_vcl_vrt.c +++ b/bin/varnishd/cache/cache_vcl_vrt.c @@ -76,16 +76,6 @@ VCL_Method_Name(unsigned m) /*--------------------------------------------------------------------*/ -void -VCL_Onboard(const struct req *req, const struct busyobj *bo) -{ - - CHECK_OBJ_ORNULL(req, REQ_MAGIC); - CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); - assert(req != NULL || bo != NULL); - assert(req == NULL || bo == NULL); -} - void VCL_Refresh(struct vcl **vcc) { @@ -335,11 +325,12 @@ VRT_vcl_select(VRT_CTX, VCL_VCL vcl) struct req *req = ctx->req; CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC); + VCL_TaskLeave(req->vcl, req->privs); VCL_Rel(&req->vcl); vcl_get(&req->vcl, vcl); /* XXX: better logging */ VSLb(ctx->req->vsl, SLT_Debug, "Now using %s VCL", vcl->loaded_name); - VCL_Onboard(req, NULL); + VCL_TaskEnter(req->vcl, req->privs); } struct vclref * diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 2e8a8961b..af59b6a0b 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -633,7 +633,8 @@ VRT_Rollback(VRT_CTX, VCL_HTTP hp) } else if (hp == ctx->http_bereq) { CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); // -> VBO_Rollback ? - VRTPRIV_dynamic_kill(ctx->bo->privs, (uintptr_t)ctx->bo); + VCL_TaskLeave(ctx->bo->vcl, ctx->bo->privs); + VCL_TaskEnter(ctx->bo->vcl, ctx->bo->privs); HTTP_Copy(ctx->bo->bereq, ctx->bo->bereq0); WS_Reset(ctx->bo->bereq->ws, ctx->bo->ws_bo); WS_Reset(ctx->bo->ws, ctx->bo->ws_bo); diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index b29f12047..1d7aff5a2 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -190,3 +190,31 @@ VRT_priv_fini(const struct vmod_priv *p) if (p->priv != NULL && p->free != NULL) p->free(p->priv); } + +/*--------------------------------------------------------------------*/ + +void +VCL_TaskEnter(struct vcl *vcl, struct vrt_privs *privs) +{ + + VSL(SLT_Debug, 0, "%s %p %p %u", __func__, vcl, privs, privs->magic); + AN(vcl); + AZ(privs->magic); + VRTPRIV_init(privs); +} + +void +VCL_TaskLeave(struct vcl *vcl, struct vrt_privs *privs) +{ + struct vrt_priv *vp, *vp1; + + AN(vcl); + VSL(SLT_Debug, 0, "%s %p %p %u", __func__, vcl, privs, privs->magic); + CHECK_OBJ_NOTNULL(privs, VRT_PRIVS_MAGIC); + VTAILQ_FOREACH_SAFE(vp, &privs->privs, list, vp1) { + VTAILQ_REMOVE(&privs->privs, vp, list); + VRT_priv_fini(vp->priv); + } + INIT_OBJ(privs, 0); +} + diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index 30bd3b894..b339339f5 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -286,7 +286,6 @@ http1_dissect(struct worker *wrk, struct req *req) VCL_Refresh(&wrk->vcl); req->vcl = wrk->vcl; wrk->vcl = NULL; - VCL_Onboard(req, NULL); HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); req->err_code = HTTP1_DissectRequest(req->htc, req->http); diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index 644474309..f6ea07eae 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -643,7 +643,6 @@ h2_rx_headers(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) VCL_Refresh(&wrk->vcl); req->vcl = wrk->vcl; wrk->vcl = NULL; - VCL_Onboard(req, NULL); req->acct.req_hdrbytes += h2->rxf_len; HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod); From phk at FreeBSD.org Tue Aug 28 21:44:07 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2018 21:44:07 +0000 (UTC) Subject: [master] 62d0cdd89 Make each event sent to compiled VCL a separate task as far as per-task PRIVs. Message-ID: <20180828214407.AF36091B8A@lists.varnish-cache.org> commit 62d0cdd890f8bd0c324d391af69713b0e11884c2 Author: Poul-Henning Kamp Date: Tue Aug 28 21:42:08 2018 +0000 Make each event sent to compiled VCL a separate task as far as per-task PRIVs. Fixes: #2749 diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index 0a63c0401..cf8a952db 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -121,7 +121,6 @@ vcl_get_ctx(unsigned method, int msg) } ctx_cli.ws = &ws_cli; WS_Assert(ctx_cli.ws); - VRTPRIV_init(cli_task_privs); return (&ctx_cli); } @@ -138,7 +137,6 @@ vcl_rel_ctx(struct vrt_ctx **ctx) WS_Reset(&ws_cli, ws_snapshot_cli); INIT_OBJ(*ctx, VRT_CTX_MAGIC); *ctx = NULL; - VRTPRIV_dynamic_kill(cli_task_privs, (uintptr_t)cli_task_privs); } /*--------------------------------------------------------------------*/ @@ -163,7 +161,9 @@ vcl_send_event(VRT_CTX, enum vcl_event_e ev) if (ev == VCL_EVENT_LOAD || ev == VCL_EVENT_WARM) AN(ctx->msg); + VCL_TaskEnter(ctx->vcl, cli_task_privs); r = ctx->vcl->conf->event_vcl(ctx, ev); + VCL_TaskLeave(ctx->vcl, cli_task_privs); if (r && (ev == VCL_EVENT_COLD || ev == VCL_EVENT_DISCARD)) WRONG("A VMOD cannot fail COLD or DISCARD events"); From phk at FreeBSD.org Tue Aug 28 21:44:07 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Tue, 28 Aug 2018 21:44:07 +0000 (UTC) Subject: [master] a5ff2d3d4 Removing debugging Message-ID: <20180828214407.9EB5C91B87@lists.varnish-cache.org> commit a5ff2d3d44e5ae19d8573c00e9f203a34eac00c8 Author: Poul-Henning Kamp Date: Tue Aug 28 21:36:48 2018 +0000 Removing debugging diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 1d7aff5a2..3d8606b43 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -197,7 +197,6 @@ void VCL_TaskEnter(struct vcl *vcl, struct vrt_privs *privs) { - VSL(SLT_Debug, 0, "%s %p %p %u", __func__, vcl, privs, privs->magic); AN(vcl); AZ(privs->magic); VRTPRIV_init(privs); @@ -209,7 +208,6 @@ VCL_TaskLeave(struct vcl *vcl, struct vrt_privs *privs) struct vrt_priv *vp, *vp1; AN(vcl); - VSL(SLT_Debug, 0, "%s %p %p %u", __func__, vcl, privs, privs->magic); CHECK_OBJ_NOTNULL(privs, VRT_PRIVS_MAGIC); VTAILQ_FOREACH_SAFE(vp, &privs->privs, list, vp1) { VTAILQ_REMOVE(&privs->privs, vp, list); From phk at FreeBSD.org Wed Aug 29 05:15:13 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Wed, 29 Aug 2018 05:15:13 +0000 (UTC) Subject: [master] b78a4672d Privatize stuff. Message-ID: <20180829051513.645699BF48@lists.varnish-cache.org> commit b78a4672d6b27c1d662f43dca307061b84229799 Author: Poul-Henning Kamp Date: Wed Aug 29 05:13:48 2018 +0000 Privatize stuff. diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index 154a6796b..cb1d295a5 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -387,8 +387,8 @@ void VCL_Poll(void); void VCL_Ref(struct vcl *); void VCL_Refresh(struct vcl **); void VCL_Rel(struct vcl **); -void VCL_TaskEnter(struct vcl *, struct vrt_privs *); -void VCL_TaskLeave(struct vcl *, struct vrt_privs *); +void VCL_TaskEnter(const struct vcl *, struct vrt_privs *); +void VCL_TaskLeave(const struct vcl *, struct vrt_privs *); const char *VCL_Return_Name(unsigned); const char *VCL_Method_Name(unsigned); void VCL_Bo2Ctx(struct vrt_ctx *, struct busyobj *); @@ -409,8 +409,6 @@ void VCL_VRT_Init(void); int VCL_StackVFP(struct vfp_ctx *, const struct vcl *, const char *); /* cache_vrt.c */ -void VRTPRIV_init(struct vrt_privs *privs); -void VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id); void pan_privs(struct vsb *, const struct vrt_privs *); /* cache_vrt_priv.c */ diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 3d8606b43..e4dd16479 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -83,7 +83,7 @@ pan_privs(struct vsb *vsb, const struct vrt_privs *privs) /*-------------------------------------------------------------------- */ -void +static void VRTPRIV_init(struct vrt_privs *privs) { @@ -117,23 +117,6 @@ vrt_priv_dynamic(const struct vcl *vcl, struct ws *ws, return (vp->priv); } -void -VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id) -{ - struct vrt_priv *vp, *vp1; - - CHECK_OBJ_NOTNULL(privs, VRT_PRIVS_MAGIC); - AN(id); - - VTAILQ_FOREACH_SAFE(vp, &privs->privs, list, vp1) { - CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC); - if (id == vp->id) { - VTAILQ_REMOVE(&privs->privs, vp, list); - VRT_priv_fini(vp->priv); - } - } -} - struct vmod_priv * VRT_priv_task(VRT_CTX, const void *vmod_id) { @@ -194,7 +177,7 @@ VRT_priv_fini(const struct vmod_priv *p) /*--------------------------------------------------------------------*/ void -VCL_TaskEnter(struct vcl *vcl, struct vrt_privs *privs) +VCL_TaskEnter(const struct vcl *vcl, struct vrt_privs *privs) { AN(vcl); @@ -203,7 +186,7 @@ VCL_TaskEnter(struct vcl *vcl, struct vrt_privs *privs) } void -VCL_TaskLeave(struct vcl *vcl, struct vrt_privs *privs) +VCL_TaskLeave(const struct vcl *vcl, struct vrt_privs *privs) { struct vrt_priv *vp, *vp1; From nils.goroll at uplex.de Wed Aug 29 06:14:09 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 29 Aug 2018 06:14:09 +0000 (UTC) Subject: [master] fbb7c198c add a test for task_priv allocation in the function prologue Message-ID: <20180829061409.8210E9D091@lists.varnish-cache.org> commit fbb7c198c906bb4a54f15a46caeabe88e5cc04b8 Author: Nils Goroll Date: Wed Aug 22 14:02:54 2018 +0200 add a test for task_priv allocation in the function prologue diff --git a/bin/varnishtest/tests/m00000.vtc b/bin/varnishtest/tests/m00000.vtc index 5c0fa7536..355bb3c56 100644 --- a/bin/varnishtest/tests/m00000.vtc +++ b/bin/varnishtest/tests/m00000.vtc @@ -20,7 +20,17 @@ varnish v1 -vcl+backend { set req.http.overwrite = "the workspace " + "to ensure we notice any unfinished privs"; } + + sub priv_task { + debug.test_priv_task("foo"); + } + sub vcl_recv { + if (req.url == "/priv-task-no-mem") { + vtc.workspace_alloc(client, -4); + call priv_task; + return (fail); + } if (req.url == "/fail") { debug.test_priv_task("foo"); return (fail); @@ -65,6 +75,12 @@ client c1 { expect resp.status == 503 } -run +client c1 { + txreq -url "/priv-task-no-mem" + rxresp + expect resp.status == 503 +} -run + varnish v1 -expect DEBUG.count == 1 logexpect l1 -v v1 -g raw -d 1 { From nils.goroll at uplex.de Wed Aug 29 06:14:09 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Wed, 29 Aug 2018 06:14:09 +0000 (UTC) Subject: [master] f03948f48 initialize PRIV_TASK and PRIV_TOP vmod arguments once per subroutine Message-ID: <20180829061409.6C42D9D08F@lists.varnish-cache.org> commit f03948f48445be4dbea5f389ac4168b4a6befc6c Author: Nils Goroll Date: Tue Aug 14 14:02:34 2018 +0200 initialize PRIV_TASK and PRIV_TOP vmod arguments once per subroutine ... and fail the VCL unless successful. Providing the PRIVs to vmods is a core function, so error handling should happen outside vmods. Besides being safe, this initialization can be more efficient than previous code for PRIVs used frequently within the same subroutine. An alternative approach would be to initialize all privs once per task / top request, but unless all privs are actually used in a VCL, this approach could impose significant overhead, both in terms of time and memory. By initializing privs once per sub, we impose overhead for privs which are referenced but not actually used in a subroutine, but not for all of the vcl. Fixes #2708 diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index a7dfc98d3..1adc26721 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -104,6 +104,8 @@ vcc_NewProc(struct vcc *tl, struct symbol *sym) AN(p); VTAILQ_INIT(&p->calls); VTAILQ_INIT(&p->uses); + VTAILQ_INIT(&p->priv_tasks); + VTAILQ_INIT(&p->priv_tops); VTAILQ_INSERT_TAIL(&tl->procs, p, list); p->prologue = VSB_new_auto(); AN(p->prologue); diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index befc15a94..4e67b538c 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -174,6 +174,7 @@ struct symbol { }; VTAILQ_HEAD(tokenhead, token); +VTAILQ_HEAD(procprivhead, procpriv); struct proc { unsigned magic; @@ -181,6 +182,8 @@ struct proc { const struct method *method; VTAILQ_HEAD(,proccall) calls; VTAILQ_HEAD(,procuse) uses; + struct procprivhead priv_tasks; + struct procprivhead priv_tops; VTAILQ_ENTRY(proc) list; struct token *name; unsigned ret_bitmap; @@ -389,6 +392,8 @@ int vcc_CheckAction(struct vcc *tl); void vcc_AddUses(struct vcc *, const struct token *, const struct token *, unsigned mask, const char *use); int vcc_CheckUses(struct vcc *tl); +const char *vcc_MarkPriv(struct vcc *, struct procprivhead *, + const char *); #define ERRCHK(tl) do { if ((tl)->err) return; } while (0) #define ErrInternal(tl) vcc__ErrInternal(tl, __func__, __LINE__) diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index e016696a5..1f0699e19 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -399,31 +399,49 @@ vcc_Eval_Var(struct vcc *tl, struct expr **e, struct token *t, */ static struct expr * -vcc_priv_arg(struct vcc *tl, const char *p, const char *name, const char *vmod) +vcc_priv_arg(struct vcc *tl, const char *p, const struct symbol *sym) { - struct expr *e2; - char buf[32]; + char buf[64]; struct inifin *ifp; + const char *vmod, *f = NULL; + struct procprivhead *marklist = NULL; + + AN(sym); + AN(sym->vmod); + vmod = sym->vmod; - (void)name; if (!strcmp(p, "PRIV_VCL")) { - e2 = vcc_mk_expr(VOID, "&vmod_priv_%s", vmod); + return (vcc_mk_expr(VOID, "&vmod_priv_%s", vmod)); } else if (!strcmp(p, "PRIV_CALL")) { bprintf(buf, "vmod_priv_%u", tl->unique++); ifp = New_IniFin(tl); Fh(tl, 0, "static struct vmod_priv %s;\n", buf); VSB_printf(ifp->fin, "\tVRT_priv_fini(&%s);", buf); - e2 = vcc_mk_expr(VOID, "&%s", buf); + return (vcc_mk_expr(VOID, "&%s", buf)); } else if (!strcmp(p, "PRIV_TASK")) { - e2 = vcc_mk_expr(VOID, - "VRT_priv_task(ctx, &VGC_vmod_%s)", vmod); + f = "task"; + marklist = &tl->curproc->priv_tasks; } else if (!strcmp(p, "PRIV_TOP")) { - e2 = vcc_mk_expr(VOID, - "VRT_priv_top(ctx, &VGC_vmod_%s)", vmod); + f = "top"; + marklist = &tl->curproc->priv_tops; } else { WRONG("Wrong PRIV_ type"); } - return (e2); + AN(f); + AN(marklist); + bprintf(buf, "ARG_priv_%s_%s", f, vmod); + + if (vcc_MarkPriv(tl, marklist, vmod) == NULL) + VSB_printf(tl->curproc->prologue, + " struct vmod_priv *%s = " + "VRT_priv_%s(ctx, &VGC_vmod_%s);\n" + " if (%s == NULL) {\n" + " VRT_fail(ctx, \"failed to get %s priv " + "for vmod %s\");\n" + " return;\n" + " }\n", + buf, f, vmod, buf, f, vmod); + return (vcc_mk_expr(VOID, "%s", buf)); } struct func_arg { @@ -522,8 +540,7 @@ vcc_func(struct vcc *tl, struct expr **e, const void *priv, vvp = VTAILQ_FIRST(&vv->children); if (!memcmp(vvp->value, "PRIV_", 5)) { - fa->result = vcc_priv_arg(tl, vvp->value, - sym->name, sym->vmod); + fa->result = vcc_priv_arg(tl, vvp->value, sym); continue; } fa->type = VCC_Type(vvp->value); diff --git a/lib/libvcc/vcc_xref.c b/lib/libvcc/vcc_xref.c index 31d3bc6cd..bfa98a6f6 100644 --- a/lib/libvcc/vcc_xref.c +++ b/lib/libvcc/vcc_xref.c @@ -39,6 +39,7 @@ #include "config.h" +#include #include "vcc_compile.h" /*--------------------------------------------------------------------*/ @@ -59,6 +60,11 @@ struct procuse { struct proc *fm; }; +struct procpriv { + VTAILQ_ENTRY(procpriv) list; + const char *vmod; +}; + /*--------------------------------------------------------------------*/ static void @@ -355,3 +361,28 @@ VCC_XrefTable(struct vcc *tl) VCC_WalkSymbols(tl, vcc_xreftable, SYM_NONE); Fc(tl, 0, "*/\n\n"); } + +/*--------------------------------------------------------------------- + * mark vmod as referenced, return NULL if not yet marked, vmod if marked + */ + +const char * +vcc_MarkPriv(struct vcc *tl, struct procprivhead *head, + const char *vmod) +{ + struct procpriv *pp; + + AN(vmod); + + VTAILQ_FOREACH(pp, head, list) { + if (pp->vmod == vmod) + return (vmod); + AN(strcmp(pp->vmod, vmod)); + } + + pp = TlAlloc(tl, sizeof *pp); + assert(pp != NULL); + pp->vmod = vmod; + VTAILQ_INSERT_TAIL(head, pp, list); + return (NULL); +} From dmatetelki at varnish-software.com Wed Aug 29 14:26:10 2018 From: dmatetelki at varnish-software.com (Denes Matetelki) Date: Wed, 29 Aug 2018 14:26:10 +0000 (UTC) Subject: [6.0] 8d54bec53 Prepare for 6.0.1 Message-ID: <20180829142610.660CCA8128@lists.varnish-cache.org> commit 8d54bec5330c29304979ebf2c425ae14ab80493c Author: Denes Matetelki Date: Wed Aug 29 11:52:28 2018 +0200 Prepare for 6.0.1 diff --git a/configure.ac b/configure.ac index d56dadf62..3fa117537 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT([Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2018 Varnish Software]) AC_REVISION([$Id$]) -AC_INIT([Varnish], [6.0.0], [varnish-dev at varnish-cache.org]) +AC_INIT([Varnish], [6.0.1], [varnish-dev at varnish-cache.org]) AC_CONFIG_SRCDIR(include/miniobj.h) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/changes.rst b/doc/changes.rst index d48a50b2f..ce5859699 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -28,7 +28,7 @@ release process. ================================ -Varnish Cache 6.0.1 (ongoing) +Varnish Cache 6.0.1 (2018-08-29) ================================ * Added std.fnmatch() (2737_) From phk at FreeBSD.org Thu Aug 30 07:55:13 2018 From: phk at FreeBSD.org (Poul-Henning Kamp) Date: Thu, 30 Aug 2018 07:55:13 +0000 (UTC) Subject: [master] 20ab2abc3 Only dlclose() Vmods after all "fini" processing. Message-ID: <20180830075513.D741B932E9@lists.varnish-cache.org> commit 20ab2abc36781b03605785c0a9ae463460cdffef Author: Poul-Henning Kamp Date: Thu Aug 30 07:53:32 2018 +0000 Only dlclose() Vmods after all "fini" processing. diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c index cf8a952db..dd3267ea2 100644 --- a/bin/varnishd/cache/cache_vcl.c +++ b/bin/varnishd/cache/cache_vcl.c @@ -533,7 +533,7 @@ vcl_cancel_load(VRT_CTX, struct cli *cli, const char *name, const char *step) if (VSB_len(ctx->msg)) VCLI_Out(cli, "\nMessage:\n\t%s", VSB_data(ctx->msg)); *ctx->handling = 0; - AZ(vcl->conf->event_vcl(ctx, VCL_EVENT_DISCARD)); + AZ(vcl_send_event(ctx, VCL_EVENT_DISCARD)); vcl_KillBackends(vcl); free(vcl->loaded_name); VCL_Close(&vcl); diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c index 25a119da4..af49ef40b 100644 --- a/bin/varnishd/cache/cache_vrt_vmod.c +++ b/bin/varnishd/cache/cache_vrt_vmod.c @@ -162,7 +162,7 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, unsigned nbr, void *ptr, int len, } void -VRT_Vmod_Fini(struct vmod **hdl) +VRT_Vmod_Unload(VRT_CTX, struct vmod **hdl) { struct vmod *v; @@ -170,6 +170,9 @@ VRT_Vmod_Fini(struct vmod **hdl) TAKE_OBJ_NOTNULL(v, hdl, VMOD_MAGIC); + VCL_TaskLeave(ctx->vcl, cli_task_privs); + VCL_TaskEnter(ctx->vcl, cli_task_privs); + #ifndef DONT_DLCLOSE_VMODS /* * atexit(3) handlers are not called during dlclose(3). We don't diff --git a/include/vrt.h b/include/vrt.h index f49478fc2..0d76b2be5 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -59,6 +59,7 @@ * VRT_STRANDS_string() removed from vrt.h (never implemented) * VRT_Healthy() changed prototype * VRT_Vmod_Init signature changed + * VRT_Vmod_Fini changed to VRT_Vmod_Unload * 7.0 (2018-03-15) * lots of stuff moved from cache.h to cache_varnishd.h * (ie: from "$Abi vrt" to "$Abi strict") @@ -474,7 +475,7 @@ int VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst); /* VMOD/Modules related */ int VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, unsigned nbr, void *ptr, int len, const char *nm, const char *path, const char *file_id, const char *backup); -void VRT_Vmod_Fini(struct vmod **hdl); +void VRT_Vmod_Unload(VRT_CTX, struct vmod **hdl); /* VCL program related */ VCL_VCL VRT_vcl_get(VRT_CTX, const char *); diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c index 1adc26721..bcfaadcab 100644 --- a/lib/libvcc/vcc_compile.c +++ b/lib/libvcc/vcc_compile.c @@ -139,12 +139,16 @@ New_IniFin(struct vcc *tl) { struct inifin *p; - p = TlAlloc(tl, sizeof *p); + ALLOC_OBJ(p, INIFIN_MAGIC); AN(p); - p->magic = INIFIN_MAGIC; p->ini = VSB_new_auto(); + AN(p->ini); p->fin = VSB_new_auto(); + AN(p->fin); + p->final = VSB_new_auto(); + AN(p->final); p->event = VSB_new_auto(); + AN(p->event); p->n = ++tl->ninifin; VTAILQ_INSERT_TAIL(&tl->inifin, p, list); return (p); @@ -324,20 +328,31 @@ EmitInitFini(const struct vcc *tl) */ Fc(tl, 0, "\nstatic int\nVGC_Discard(VRT_CTX)\n{\n\n"); - Fc(tl, 0, "\tswitch (vgc_inistep) {\n\n"); + Fc(tl, 0, "\tswitch (vgc_inistep) {\n"); VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) { AZ(VSB_finish(p->fin)); if (q) assert(q->n > p->n); q = p; - if (VSB_len(p->fin)) { - Fc(tl, 0, "\t\tcase %u :\n", p->n); + Fc(tl, 0, "\t\tcase %u:\n", p->n); + if (VSB_len(p->fin)) Fc(tl, 0, "\t%s\n", VSB_data(p->fin)); - Fc(tl, 0, "\t\t\t/* FALLTHROUGH */\n"); - } + Fc(tl, 0, "\t\t\t/* FALLTHROUGH */\n"); VSB_destroy(&p->fin); } - Fc(tl, 0, "\t}\n"); + Fc(tl, 0, "\t\tdefault:\n\t\t\tbreak;\n"); + Fc(tl, 0, "\t}\n\n"); + Fc(tl, 0, "\tswitch (vgc_inistep) {\n"); + VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) { + AZ(VSB_finish(p->final)); + Fc(tl, 0, "\t\tcase %u:\n", p->n); + if (VSB_len(p->final)) + Fc(tl, 0, "\t%s\n", VSB_data(p->final)); + Fc(tl, 0, "\t\t\t/* FALLTHROUGH */\n"); + VSB_destroy(&p->final); + } + Fc(tl, 0, "\t\tdefault:\n\t\t\tbreak;\n"); + Fc(tl, 0, "\t}\n\n"); Fc(tl, 0, "\treturn (0);\n"); Fc(tl, 0, "}\n"); diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h index 4e67b538c..3a98c76e0 100644 --- a/lib/libvcc/vcc_compile.h +++ b/lib/libvcc/vcc_compile.h @@ -201,6 +201,7 @@ struct inifin { unsigned n; struct vsb *ini; struct vsb *fin; + struct vsb *final; struct vsb *event; VTAILQ_ENTRY(inifin) list; }; diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c index fd6a7acc6..babd70eef 100644 --- a/lib/libvcc/vcc_vmod.c +++ b/lib/libvcc/vcc_vmod.c @@ -105,7 +105,7 @@ vcc_json_always(struct vcc *tl, const struct symbol *msym) vv2->value, msym->name); VSB_printf(ifp->fin, "\t\t(void)%s(ctx, &vmod_priv_%s,\n" - "\t\t\t VCL_EVENT_DISCARD);\n", + "\t\t\t VCL_EVENT_DISCARD);", vv2->value, msym->name); VSB_printf(ifp->event, "%s(ctx, &vmod_priv_%s, ev)", vv2->value, msym->name); @@ -324,8 +324,9 @@ vcc_ParseImport(struct vcc *tl) VCC_INFO_PREFIX, fnp, PF(mod), vmd->file_id); /* XXX: zero the function pointer structure ?*/ - VSB_printf(ifp->fin, "\t\tVRT_priv_fini(&vmod_priv_%.*s);\n", PF(mod)); - VSB_printf(ifp->fin, "\t\t\tVRT_Vmod_Fini(&VGC_vmod_%.*s);", PF(mod)); + VSB_printf(ifp->fin, "\t\tVRT_priv_fini(&vmod_priv_%.*s);", PF(mod)); + VSB_printf(ifp->final, + "\t\tVRT_Vmod_Unload(ctx, &VGC_vmod_%.*s);", PF(mod)); vj = vjsn_parse(vmd->json, &p); XXXAZ(p); From nils.goroll at uplex.de Thu Aug 30 10:33:11 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 30 Aug 2018 10:33:11 +0000 (UTC) Subject: [master] a4f7faec4 Test that vmod code is still present when calling a task_priv .fini Message-ID: <20180830103312.06C5996603@lists.varnish-cache.org> commit a4f7faec45bf3677e7ddbafcfa3ab672dedcce63 Author: Nils Goroll Date: Thu Aug 30 12:12:42 2018 +0200 Test that vmod code is still present when calling a task_priv .fini Tests 20ab2abc36781b03605785c0a9ae463460cdffef diff --git a/bin/varnishtest/tests/r02451.vtc b/bin/varnishtest/tests/r02451.vtc index 2ff3facdc..0dc0a5a4c 100644 --- a/bin/varnishtest/tests/r02451.vtc +++ b/bin/varnishtest/tests/r02451.vtc @@ -44,8 +44,8 @@ varnish v1 -vcl+backend { logexpect l1 -v v1 -g raw -d 1 { expect 0 0 CLI {^Rd vcl.load} - expect 0 = VCL_Log {^func something to remember} - expect 0 = VCL_Log {^obj something to remember} + expect 4 = VCL_Log {^func something to remember} + expect 2 = VCL_Log {^obj something to remember} } -start client c1 { diff --git a/bin/varnishtest/tests/v00041.vtc b/bin/varnishtest/tests/v00041.vtc index 3bac4aa3d..a67928ca9 100644 --- a/bin/varnishtest/tests/v00041.vtc +++ b/bin/varnishtest/tests/v00041.vtc @@ -61,7 +61,11 @@ varnish v1 -arg "-p debug=+vclrel" -vcl+backend { logexpect l1 -v v1 -g raw -d 1 { expect 0 0 CLI {^Rd vcl.load} + expect 0 = Debug {^test_priv_task.*new.$} + expect 0 = Debug {^test_priv_task.*update.$} + expect 0 = Debug {^test_priv_task.*exists.$} expect 0 = VCL_Log {^func something to remember} + expect 0 = Debug {^test_priv_task.*exists.$} expect 0 = VCL_Log {^obj something to remember} expect * 1002 Begin fetch$ @@ -77,8 +81,14 @@ logexpect l1 -v v1 -g raw -d 1 { expect 0 = VCL_Log ^bar expect * 0 Debug {^vcl1: VCL_EVENT_COLD} + expect * 0 CLI {^Rd vcl.discard} + expect 0 = Debug {^test_priv_task.*new.$} + expect 0 = Debug {^test_priv_task.*update.$} + expect 0 = Debug {^test_priv_task.*exists.$} expect * = VCL_Log {^func cleaning up} + expect 0 = Debug {^test_priv_task.*exists.$} expect 0 = VCL_Log {^obj cleaning up} + expect 0 = Debug {^priv_task_free} } -start client c1 { diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c index 5d84206fa..a3a78975a 100644 --- a/lib/libvmod_debug/vmod_debug.c +++ b/lib/libvmod_debug/vmod_debug.c @@ -123,16 +123,27 @@ xyzzy_test_priv_call(VRT_CTX, struct vmod_priv *priv) } } +static void +priv_task_free(void *ptr) +{ + AN(ptr); + VSL(SLT_Debug, 0, "priv_task_free(%p)", ptr); + free(ptr); +} + VCL_STRING v_matchproto_(td_debug_test_priv_task) xyzzy_test_priv_task(VRT_CTX, struct vmod_priv *priv, VCL_STRING s) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (s == NULL || *s == '\0') { - return priv->priv; + VSL(SLT_Debug, 0, "test_priv_task(%p) = %p (exists)", + priv, priv->priv); } else if (priv->priv == NULL) { priv->priv = strdup(s); - priv->free = free; + priv->free = priv_task_free; + VSL(SLT_Debug, 0, "test_priv_task(%p) = %p (new)", + priv, priv->priv); } else { char *n = realloc(priv->priv, strlen(priv->priv) + strlen(s) + 2); @@ -141,7 +152,11 @@ xyzzy_test_priv_task(VRT_CTX, struct vmod_priv *priv, VCL_STRING s) strcat(n, " "); strcat(n, s); priv->priv = n; + VSL(SLT_Debug, 0, "test_priv_task(%p) = %p (update)", + priv, priv->priv); } + if (priv->priv != NULL) + assert(priv->free == priv_task_free); return (priv->priv); } From nils.goroll at uplex.de Thu Aug 30 16:05:11 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 30 Aug 2018 16:05:11 +0000 (UTC) Subject: [master] bfe1bcd8d varnishtest: add -keepalive to repeat on a single connection Message-ID: <20180830160511.62709A56C8@lists.varnish-cache.org> commit bfe1bcd8d539856ce9d91451d524740ca6b8372a Author: Nils Goroll Date: Thu Aug 30 17:44:07 2018 +0200 varnishtest: add -keepalive to repeat on a single connection For tests which do not require new connections for repetitions (for example because of possible error conditions), this reduces run time and the number of required ephemeral ports. The latter is a real issue when running many vtcs in parallel which each run many repetitions of the same test (for example to check for possible race conditions). When ephemeral ports are exhausted, seemingly unrelated issues like the following can be observed: ---- c1010 14.0 Failed to open 127.0.0.1 59763: (null) **** v1 1.8 vsl| 0 CLI - Wr 300 65 Listen failed on socket '127.0.0.1:33328': Address already in use **** v1 1.8 vsl| 0 CLI - EOF on CLI connection, worker stops An argument could be made that UDS does not suffer from the port exhaustion issue and thus such tests could be migrated to UDS. Yet also for this case the run time point remains, plus deliberately testing many iterations on a single connection could have its own merits. diff --git a/bin/varnishtest/tests/m00041.vtc b/bin/varnishtest/tests/m00041.vtc index 4c543d845..aeda981f9 100644 --- a/bin/varnishtest/tests/m00041.vtc +++ b/bin/varnishtest/tests/m00041.vtc @@ -404,7 +404,7 @@ client c1 { # Decode failures -server s1 -repeat 11 { +server s1 -repeat 11 -keepalive { rxreq txresp } -start diff --git a/bin/varnishtest/tests/m00042.vtc b/bin/varnishtest/tests/m00042.vtc index aaac4b917..6e6004f63 100644 --- a/bin/varnishtest/tests/m00042.vtc +++ b/bin/varnishtest/tests/m00042.vtc @@ -414,7 +414,7 @@ client c1 { # Decode failures -server s1 -repeat 11 { +server s1 -repeat 11 -keepalive { rxreq txresp } -start diff --git a/bin/varnishtest/tests/r01834.vtc b/bin/varnishtest/tests/r01834.vtc index 827105b8b..33437a9b2 100644 --- a/bin/varnishtest/tests/r01834.vtc +++ b/bin/varnishtest/tests/r01834.vtc @@ -4,6 +4,7 @@ varnishtest "#1834 - Buffer overflow in backend workspace" # workspace left. If failing it would be because we tripped the canary # at the end of the workspace. + server s1 -repeat 64 { rxreq txresp diff --git a/bin/varnishtest/tests/r02372.vtc b/bin/varnishtest/tests/r02372.vtc index c32d17b96..a01401f16 100644 --- a/bin/varnishtest/tests/r02372.vtc +++ b/bin/varnishtest/tests/r02372.vtc @@ -1,6 +1,6 @@ varnishtest "Count purges when there are many variants" -server s1 -repeat 72 { +server s1 -repeat 72 -keepalive { rxreq txresp -hdr "Vary: foo" } -start @@ -16,7 +16,7 @@ varnish v1 -arg "-p workspace_thread=512" -vcl+backend { } } -start -client c1 -repeat 72 { +client c1 -repeat 72 -keepalive { txreq rxresp } -run diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c index d2f72b955..5c714de0b 100644 --- a/bin/varnishtest/vtc_client.c +++ b/bin/varnishtest/vtc_client.c @@ -60,6 +60,7 @@ struct client { int proxy_version; unsigned repeat; + unsigned keepalive; unsigned running; pthread_t tp; @@ -215,7 +216,8 @@ client_thread(void *priv) if (c->repeat == 0) c->repeat = 1; if (c->repeat != 1) - vtc_log(vl, 2, "Started (%u iterations)", c->repeat); + vtc_log(vl, 2, "Started (%u iterations%s)", c->repeat, + c->keepalive ? " using keepalive" : ""); for (u = 0; u < c->repeat; u++) { char *addr = VSB_data(vsb); @@ -231,7 +233,11 @@ client_thread(void *priv) (void)VTCP_blocking(fd); if (c->proxy_spec != NULL) client_proxy(vl, fd, c->proxy_version, c->proxy_spec); - fd = http_process(vl, c->spec, fd, NULL, addr); + if (! c->keepalive) + fd = http_process(vl, c->spec, fd, NULL, addr); + else + while (fd >= 0 && u++ < c->repeat) + fd = http_process(vl, c->spec, fd, NULL, addr); vtc_log(vl, 3, "closing fd %d", fd); VTCP_close(&fd); } @@ -393,6 +399,10 @@ cmd_client(CMD_ARGS) av++; continue; } + if (!strcmp(*av, "-keepalive")) { + c->keepalive = 1; + continue; + } if (!strcmp(*av, "-start")) { client_start(c); continue; diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c index 741c5f12a..d89a91a5a 100644 --- a/bin/varnishtest/vtc_http.c +++ b/bin/varnishtest/vtc_http.c @@ -95,6 +95,10 @@ extern const struct cmds http_cmds[]; * \-repeat NUMBER * Instead of processing the specification only once, do it NUMBER times. * + * \-keepalive + * For repeat, do not open new connections but rather run all + * iterations in the same connection + * * \-break (server only) * Stop the server. * diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c index 4876352f2..d156185d9 100644 --- a/bin/varnishtest/vtc_server.c +++ b/bin/varnishtest/vtc_server.c @@ -52,6 +52,7 @@ struct server { char run; unsigned repeat; + unsigned keepalive; char *spec; int depth; @@ -234,10 +235,9 @@ server_thread(void *priv) vl = vtc_logopen(s->name); pthread_cleanup_push(vtc_logclose, vl); - vtc_log(vl, 2, "Started on %s", s->listen); + vtc_log(vl, 2, "Started on %s (%u iterations%s)", s->listen, + s->repeat, s->keepalive ? " using keepalive" : ""); for (i = 0; i < s->repeat; i++) { - if (s->repeat > 1) - vtc_log(vl, 3, "Iteration %d", i); addr = (void*)&addr_s; l = sizeof addr_s; fd = accept(s->sock, addr, &l); @@ -248,7 +248,12 @@ server_thread(void *priv) vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf); } else vtc_log(vl, 3, "accepted fd %d 0.0.0.0 0", fd); - fd = http_process(vl, s->spec, fd, &s->sock, s->listen); + if (! s->keepalive) + fd = http_process(vl, s->spec, fd, &s->sock, s->listen); + else + while (fd >= 0 && i++ < s->repeat) + fd = http_process(vl, s->spec, fd, + &s->sock, s->listen); vtc_log(vl, 3, "shutting fd %d", fd); j = shutdown(fd, SHUT_WR); if (!VTCP_Check(j)) @@ -526,6 +531,10 @@ cmd_server(CMD_ARGS) av++; continue; } + if (!strcmp(*av, "-keepalive")) { + s->keepalive = 1; + continue; + } if (!strcmp(*av, "-listen")) { if (s->sock >= 0) VTCP_close(&s->sock); From nils.goroll at uplex.de Thu Aug 30 16:05:11 2018 From: nils.goroll at uplex.de (Nils Goroll) Date: Thu, 30 Aug 2018 16:05:11 +0000 (UTC) Subject: [master] cf04d394e check if this stabilizes the test Message-ID: <20180830160511.75440A56CC@lists.varnish-cache.org> commit cf04d394e5cb122b01135cd98532c0335a6fa60f Author: Nils Goroll Date: Thu Aug 30 17:59:35 2018 +0200 check if this stabilizes the test diff --git a/bin/varnishtest/tests/b00064.vtc b/bin/varnishtest/tests/b00064.vtc index 6054ec1e6..09daf9b09 100644 --- a/bin/varnishtest/tests/b00064.vtc +++ b/bin/varnishtest/tests/b00064.vtc @@ -83,7 +83,7 @@ client c2 { expect resp.http.X-req-grace < 0. } -start -delay .1 +delay .2 # c3 asks for graced object, but now we disable grace. client c3 { From hermunn at varnish-software.com Fri Aug 31 14:56:02 2018 From: hermunn at varnish-software.com (Pål Hermunn Johansen) Date: Fri, 31 Aug 2018 14:56:02 +0000 (UTC) Subject: [master] 61dc72e07 Stabilize b000064.vtc for real Message-ID: <20180831145603.1076A9647A@lists.varnish-cache.org> commit 61dc72e07f8fd9491f229287e9be73cf5d2b88d9 Author: P?l Hermunn Johansen Date: Fri Aug 31 15:29:12 2018 +0200 Stabilize b000064.vtc for real Fixes: #2753 diff --git a/bin/varnishtest/tests/b00064.vtc b/bin/varnishtest/tests/b00064.vtc index 09daf9b09..47271831b 100644 --- a/bin/varnishtest/tests/b00064.vtc +++ b/bin/varnishtest/tests/b00064.vtc @@ -38,8 +38,11 @@ varnish v1 -vcl+backend { set req.http.X-grace = obj.grace; } sub vcl_backend_response { - set beresp.ttl = 0.1s; + set beresp.ttl = 1ms; set beresp.grace = 1m; + if (bereq.is_bgfetch) { + set beresp.http.X-was-bgfetch = "1"; + } } sub vcl_deliver { if (req.http.X-grace) { @@ -65,6 +68,7 @@ client c1 { expect resp.body == "1" expect resp.http.X-grace == expect resp.http.X-req-grace == + expect resp.http.X-was-bgfetch == } -run # let the latest object's ttl expire. @@ -81,11 +85,13 @@ client c2 { expect resp.body == "1" expect resp.http.X-grace == "60.000" expect resp.http.X-req-grace < 0. -} -start + expect resp.http.X-was-bgfetch == +} -run -delay .2 +# c3 asks for graced object, but now we disable grace. The c2 client +# started the background fetch, which will take a long time (until c4 +# has gotten its reply). -# c3 asks for graced object, but now we disable grace. client c3 { txreq -hdr "X-no-grace: true" rxresp @@ -95,6 +101,7 @@ client c3 { expect resp.body == "2" expect resp.http.X-grace == "60.000" expect resp.http.X-req-grace == "0.000" + expect resp.http.X-was-bgfetch == "1" } -start delay .1 @@ -112,9 +119,9 @@ client c4 { expect resp.body == "1" expect resp.http.X-grace == "60.000" expect resp.http.X-req-grace < 0. + expect resp.http.X-was-bgfetch == } -start -client c2 -wait client c3 -wait client c4 -wait