| GCC Code Coverage Report | |||||||||||||||||||||
        
  | 
    |||||||||||||||||||||
| Line | Branch | Exec | Source | 
1  | 
    #include <stdlib.h>  | 
    ||
2  | 
    #include <string.h>  | 
    ||
3  | 
    #define YYBYACC 1  | 
    ||
4  | 
    #define YYMAJOR 1  | 
    ||
5  | 
    #define YYMINOR 9  | 
    ||
6  | 
    #define YYLEX yylex()  | 
    ||
7  | 
    #define YYEMPTY -1  | 
    ||
8  | 
    #define yyclearin (yychar=(YYEMPTY))  | 
    ||
9  | 
    #define yyerrok (yyerrflag=0)  | 
    ||
10  | 
    #define YYRECOVERING() (yyerrflag!=0)  | 
    ||
11  | 
    #define YYPREFIX "yy"  | 
    ||
12  | 
    #line 28 "parse.y"  | 
    ||
13  | 
    #include <sys/types.h>  | 
    ||
14  | 
    #include <sys/socket.h>  | 
    ||
15  | 
    #include <sys/stat.h>  | 
    ||
16  | 
    #include <sys/queue.h>  | 
    ||
17  | 
    #include <sys/ioctl.h>  | 
    ||
18  | 
    #include <sys/time.h>  | 
    ||
19  | 
    #include <sys/tree.h>  | 
    ||
20  | 
    |||
21  | 
    #include <netinet/in.h>  | 
    ||
22  | 
    #include <arpa/inet.h>  | 
    ||
23  | 
    #include <net/if.h>  | 
    ||
24  | 
    #include <net/pfvar.h>  | 
    ||
25  | 
    #include <net/route.h>  | 
    ||
26  | 
    |||
27  | 
    #include <stdint.h>  | 
    ||
28  | 
    #include <stdarg.h>  | 
    ||
29  | 
    #include <stdio.h>  | 
    ||
30  | 
    #include <unistd.h>  | 
    ||
31  | 
    #include <ctype.h>  | 
    ||
32  | 
    #include <err.h>  | 
    ||
33  | 
    #include <endian.h>  | 
    ||
34  | 
    #include <errno.h>  | 
    ||
35  | 
    #include <limits.h>  | 
    ||
36  | 
    #include <netdb.h>  | 
    ||
37  | 
    #include <string.h>  | 
    ||
38  | 
    #include <ifaddrs.h>  | 
    ||
39  | 
    #include <syslog.h>  | 
    ||
40  | 
    #include <md5.h>  | 
    ||
41  | 
    |||
42  | 
    #include "relayd.h"  | 
    ||
43  | 
    #include "http.h"  | 
    ||
44  | 
    #include "snmp.h"  | 
    ||
45  | 
    |||
46  | 
    TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);  | 
    ||
47  | 
    static struct file { | 
    ||
48  | 
    TAILQ_ENTRY(file) entry;  | 
    ||
49  | 
    FILE *stream;  | 
    ||
50  | 
    char *name;  | 
    ||
51  | 
    int lineno;  | 
    ||
52  | 
    int errors;  | 
    ||
53  | 
    } *file, *topfile;  | 
    ||
54  | 
    struct file *pushfile(const char *, int);  | 
    ||
55  | 
    int popfile(void);  | 
    ||
56  | 
    int check_file_secrecy(int, const char *);  | 
    ||
57  | 
    int yyparse(void);  | 
    ||
58  | 
    int yylex(void);  | 
    ||
59  | 
    int yyerror(const char *, ...);  | 
    ||
60  | 
    int kw_cmp(const void *, const void *);  | 
    ||
61  | 
    int lookup(char *);  | 
    ||
62  | 
    int lgetc(int);  | 
    ||
63  | 
    int lungetc(int);  | 
    ||
64  | 
    int findeol(void);  | 
    ||
65  | 
    |||
66  | 
    TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);  | 
    ||
67  | 
    struct sym { | 
    ||
68  | 
    TAILQ_ENTRY(sym) entry;  | 
    ||
69  | 
    int used;  | 
    ||
70  | 
    int persist;  | 
    ||
71  | 
    char *nam;  | 
    ||
72  | 
    char *val;  | 
    ||
73  | 
    };  | 
    ||
74  | 
    int symset(const char *, const char *, int);  | 
    ||
75  | 
    char *symget(const char *);  | 
    ||
76  | 
    |||
77  | 
    struct relayd *conf = NULL;  | 
    ||
78  | 
    static int errors = 0;  | 
    ||
79  | 
    static int loadcfg = 0;  | 
    ||
80  | 
    objid_t last_rdr_id = 0;  | 
    ||
81  | 
    objid_t last_table_id = 0;  | 
    ||
82  | 
    objid_t last_host_id = 0;  | 
    ||
83  | 
    objid_t last_relay_id = 0;  | 
    ||
84  | 
    objid_t last_proto_id = 0;  | 
    ||
85  | 
    objid_t last_rt_id = 0;  | 
    ||
86  | 
    objid_t last_nr_id = 0;  | 
    ||
87  | 
    objid_t last_key_id = 0;  | 
    ||
88  | 
    |||
89  | 
    static struct rdr *rdr = NULL;  | 
    ||
90  | 
    static struct table *table = NULL;  | 
    ||
91  | 
    static struct relay *rlay = NULL;  | 
    ||
92  | 
    static struct host *hst = NULL;  | 
    ||
93  | 
    struct relaylist relays;  | 
    ||
94  | 
    static struct protocol *proto = NULL;  | 
    ||
95  | 
    static struct relay_rule *rule = NULL;  | 
    ||
96  | 
    static struct router *router = NULL;  | 
    ||
97  | 
    static int label = 0;  | 
    ||
98  | 
    static int tagged = 0;  | 
    ||
99  | 
    static int tag = 0;  | 
    ||
100  | 
    static in_port_t tableport = 0;  | 
    ||
101  | 
    static int dstmode;  | 
    ||
102  | 
    static enum key_type keytype = KEY_TYPE_NONE;  | 
    ||
103  | 
    static enum direction dir = RELAY_DIR_ANY;  | 
    ||
104  | 
    static char *rulefile = NULL;  | 
    ||
105  | 
    static union hashkey *hashkey = NULL;  | 
    ||
106  | 
    |||
107  | 
    struct address *host_v4(const char *);  | 
    ||
108  | 
    struct address *host_v6(const char *);  | 
    ||
109  | 
    int host_dns(const char *, struct addresslist *,  | 
    ||
110  | 
    int, struct portrange *, const char *, int);  | 
    ||
111  | 
    int host_if(const char *, struct addresslist *,  | 
    ||
112  | 
    int, struct portrange *, const char *, int);  | 
    ||
113  | 
    int host(const char *, struct addresslist *,  | 
    ||
114  | 
    int, struct portrange *, const char *, int);  | 
    ||
115  | 
    void host_free(struct addresslist *);  | 
    ||
116  | 
    |||
117  | 
    struct table *table_inherit(struct table *);  | 
    ||
118  | 
    int relay_id(struct relay *);  | 
    ||
119  | 
    struct relay *relay_inherit(struct relay *, struct relay *);  | 
    ||
120  | 
    int getservice(char *);  | 
    ||
121  | 
    int is_if_in_group(const char *, const char *);  | 
    ||
122  | 
    |||
123  | 
    typedef struct { | 
    ||
124  | 
    	union { | 
    ||
125  | 
    int64_t number;  | 
    ||
126  | 
    char *string;  | 
    ||
127  | 
    struct host *host;  | 
    ||
128  | 
    struct timeval tv;  | 
    ||
129  | 
    struct table *table;  | 
    ||
130  | 
    struct portrange port;  | 
    ||
131  | 
    		struct { | 
    ||
132  | 
    union hashkey key;  | 
    ||
133  | 
    int keyset;  | 
    ||
134  | 
    } key;  | 
    ||
135  | 
    enum direction dir;  | 
    ||
136  | 
    		struct { | 
    ||
137  | 
    struct sockaddr_storage ss;  | 
    ||
138  | 
    char name[HOST_NAME_MAX+1];  | 
    ||
139  | 
    } addr;  | 
    ||
140  | 
    		struct { | 
    ||
141  | 
    enum digest_type type;  | 
    ||
142  | 
    char *digest;  | 
    ||
143  | 
    } digest;  | 
    ||
144  | 
    } v;  | 
    ||
145  | 
    int lineno;  | 
    ||
146  | 
    } YYSTYPE;  | 
    ||
147  | 
    |||
148  | 
    #line 149 "parse.c"  | 
    ||
149  | 
    #define ALL 257  | 
    ||
150  | 
    #define APPEND 258  | 
    ||
151  | 
    #define BACKLOG 259  | 
    ||
152  | 
    #define BACKUP 260  | 
    ||
153  | 
    #define BUFFER 261  | 
    ||
154  | 
    #define CA 262  | 
    ||
155  | 
    #define CACHE 263  | 
    ||
156  | 
    #define SET 264  | 
    ||
157  | 
    #define CHECK 265  | 
    ||
158  | 
    #define CIPHERS 266  | 
    ||
159  | 
    #define CODE 267  | 
    ||
160  | 
    #define COOKIE 268  | 
    ||
161  | 
    #define DEMOTE 269  | 
    ||
162  | 
    #define DIGEST 270  | 
    ||
163  | 
    #define DISABLE 271  | 
    ||
164  | 
    #define ERROR 272  | 
    ||
165  | 
    #define EXPECT 273  | 
    ||
166  | 
    #define PASS 274  | 
    ||
167  | 
    #define BLOCK 275  | 
    ||
168  | 
    #define EXTERNAL 276  | 
    ||
169  | 
    #define FILENAME 277  | 
    ||
170  | 
    #define FORWARD 278  | 
    ||
171  | 
    #define FROM 279  | 
    ||
172  | 
    #define HASH 280  | 
    ||
173  | 
    #define HEADER 281  | 
    ||
174  | 
    #define HOST 282  | 
    ||
175  | 
    #define ICMP 283  | 
    ||
176  | 
    #define INCLUDE 284  | 
    ||
177  | 
    #define INET 285  | 
    ||
178  | 
    #define INET6 286  | 
    ||
179  | 
    #define INTERFACE 287  | 
    ||
180  | 
    #define INTERVAL 288  | 
    ||
181  | 
    #define IP 289  | 
    ||
182  | 
    #define LABEL 290  | 
    ||
183  | 
    #define LISTEN 291  | 
    ||
184  | 
    #define VALUE 292  | 
    ||
185  | 
    #define LOADBALANCE 293  | 
    ||
186  | 
    #define LOG 294  | 
    ||
187  | 
    #define LOOKUP 295  | 
    ||
188  | 
    #define METHOD 296  | 
    ||
189  | 
    #define MODE 297  | 
    ||
190  | 
    #define NAT 298  | 
    ||
191  | 
    #define NO 299  | 
    ||
192  | 
    #define DESTINATION 300  | 
    ||
193  | 
    #define NODELAY 301  | 
    ||
194  | 
    #define NOTHING 302  | 
    ||
195  | 
    #define ON 303  | 
    ||
196  | 
    #define PARENT 304  | 
    ||
197  | 
    #define PATH 305  | 
    ||
198  | 
    #define PFTAG 306  | 
    ||
199  | 
    #define PORT 307  | 
    ||
200  | 
    #define PREFORK 308  | 
    ||
201  | 
    #define PRIORITY 309  | 
    ||
202  | 
    #define PROTO 310  | 
    ||
203  | 
    #define QUERYSTR 311  | 
    ||
204  | 
    #define REAL 312  | 
    ||
205  | 
    24  | 
    #define REDIRECT 313  | 
    |
206  | 
    24  | 
    #define RELAY 314  | 
    |
207  | 
    #define REMOVE 315  | 
    ||
208  | 
    #define REQUEST 316  | 
    ||
209  | 
    #define RESPONSE 317  | 
    ||
210  | 
    #define RETRY 318  | 
    ||
211  | 
    #define QUICK 319  | 
    ||
212  | 
    #define RETURN 320  | 
    ||
213  | 
    #define ROUNDROBIN 321  | 
    ||
214  | 
    #define ROUTE 322  | 
    ||
215  | 
    #define SACK 323  | 
    ||
216  | 
    #define SCRIPT 324  | 
    ||
217  | 
    #define SEND 325  | 
    ||
218  | 
    #define SESSION 326  | 
    ||
219  | 
    #define SNMP 327  | 
    ||
220  | 
    #define SOCKET 328  | 
    ||
221  | 
    #define SPLICE 329  | 
    ||
222  | 
    #define SSL 330  | 
    ||
223  | 
    #define STICKYADDR 331  | 
    ||
224  | 
    #define STYLE 332  | 
    ||
225  | 
    #define TABLE 333  | 
    ||
226  | 
    #define TAG 334  | 
    ||
227  | 
    #define TAGGED 335  | 
    ||
228  | 
    #define TCP 336  | 
    ||
229  | 
    #define TIMEOUT 337  | 
    ||
230  | 
    #define TLS 338  | 
    ||
231  | 
    #define TO 339  | 
    ||
232  | 
    416  | 
    #define ROUTER 340  | 
    |
233  | 
    548  | 
    #define RTLABEL 341  | 
    |
234  | 
    132  | 
    #define TRANSPARENT 342  | 
    |
235  | 
    #define TRAP 343  | 
    ||
236  | 
    416  | 
    #define UPDATES 344  | 
    |
237  | 
    548  | 
    #define URL 345  | 
    |
238  | 
    132  | 
    #define VIRTUAL 346  | 
    |
239  | 
    #define WITH 347  | 
    ||
240  | 
    #define TTL 348  | 
    ||
241  | 
    #define RTABLE 349  | 
    ||
242  | 
    #define MATCH 350  | 
    ||
243  | 
    #define PARAMS 351  | 
    ||
244  | 
    #define RANDOM 352  | 
    ||
245  | 
    #define LEASTSTATES 353  | 
    ||
246  | 
    #define SRCHASH 354  | 
    ||
247  | 
    #define KEY 355  | 
    ||
248  | 
    #define CERTIFICATE 356  | 
    ||
249  | 
    #define PASSWORD 357  | 
    ||
250  | 
    #define ECDH 358  | 
    ||
251  | 
    #define EDH 359  | 
    ||
252  | 
    #define CURVE 360  | 
    ||
253  | 
    #define TICKETS 361  | 
    ||
254  | 
    #define STRING 362  | 
    ||
255  | 
    #define NUMBER 363  | 
    ||
256  | 
    #define YYERRCODE 256  | 
    ||
257  | 
    const short yylhs[] =  | 
    ||
258  | 
    	{                                        -1, | 
    ||
259  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
260  | 
    0, 31, 39, 39, 14, 14, 15, 15, 6, 1,  | 
    ||
261  | 
    1, 17, 17, 17, 16, 16, 16, 40, 40, 43,  | 
    ||
262  | 
    43, 41, 22, 22, 32, 44, 44, 33, 33, 33,  | 
    ||
263  | 
    33, 33, 9, 9, 7, 7, 45, 34, 47, 47,  | 
    ||
264  | 
    48, 48, 48, 48, 48, 48, 48, 18, 18, 12,  | 
    ||
265  | 
    12, 12, 3, 51, 35, 50, 50, 52, 52, 53,  | 
    ||
266  | 
    140  | 
    53, 54, 54, 56, 28, 55, 55, 57, 57, 57,  | 
    |
267  | 
    148  | 
    57, 57, 57, 30, 30, 58, 58, 58, 58, 58,  | 
    |
268  | 
    8  | 
    58, 58, 26, 27, 27, 60, 37, 59, 59, 59,  | 
    |
269  | 
    ✓✓ | 956  | 
    61, 61, 62, 62, 62, 62, 62, 62, 62, 62,  | 
    
270  | 
    66, 66, 65, 65, 65, 65, 65, 65, 65, 65,  | 
    ||
271  | 
    ✓✗ | 8  | 
    65, 64, 64, 63, 63, 63, 63, 63, 63, 63,  | 
    
272  | 
    63, 63, 63, 63, 63, 63, 63, 11, 71, 67,  | 
    ||
273  | 
    19, 19, 19, 29, 29, 29, 8, 8, 20, 20,  | 
    ||
274  | 
    8  | 
    20, 68, 69, 70, 70, 72, 72, 73, 73, 73,  | 
    |
275  | 
    8  | 
    73, 73, 73, 73, 73, 73, 73, 73, 73, 73,  | 
    |
276  | 
    8  | 
    73, 73, 73, 73, 73, 4, 4, 21, 21, 21,  | 
    |
277  | 
    21, 21, 21, 74, 36, 75, 75, 76, 76, 76,  | 
    ||
278  | 
    948  | 
    76, 76, 76, 77, 77, 77, 77, 10, 10, 10,  | 
    |
279  | 
    10, 10, 10, 10, 79, 38, 80, 80, 81, 81,  | 
    ||
280  | 
    948  | 
    81, 81, 81, 81, 78, 78, 78, 2, 2, 83,  | 
    |
281  | 
    23, 82, 82, 84, 84, 85, 85, 85, 85, 24,  | 
    ||
282  | 
    13, 13, 25, 42, 42, 42, 46, 46, 49, 5,  | 
    ||
283  | 
    5,  | 
    ||
284  | 
    };  | 
    ||
285  | 
    const short yylen[] =  | 
    ||
286  | 
    	{                                         2, | 
    ||
287  | 
    0, 3, 2, 3, 3, 3, 3, 3, 3, 3,  | 
    ||
288  | 
    3, 2, 1, 1, 0, 1, 0, 2, 1, 0,  | 
    ||
289  | 
    2, 0, 1, 1, 0, 1, 1, 3, 1, 0,  | 
    ||
290  | 
    1, 2, 2, 2, 3, 1, 1, 2, 2, 2,  | 
    ||
291  | 
    2, 3, 0, 1, 1, 1, 0, 7, 3, 2,  | 
    ||
292  | 
    4, 6, 1, 1, 3, 3, 1, 0, 1, 1,  | 
    ||
293  | 
    1, 2, 3, 0, 4, 2, 1, 1, 4, 3,  | 
    ||
294  | 
    2, 1, 1, 0, 3, 2, 1, 2, 1, 2,  | 
    ||
295  | 
    2, 2, 3, 0, 1, 1, 1, 1, 5, 4,  | 
    ||
296  | 
    5, 2, 2, 1, 1, 0, 5, 0, 2, 4,  | 
    ||
297  | 
    3, 2, 2, 4, 2, 4, 3, 5, 1, 1,  | 
    ||
298  | 
    3, 1, 1, 2, 1, 2, 1, 2, 2, 3,  | 
    ||
299  | 
    3, 3, 1, 2, 3, 2, 2, 1, 3, 2,  | 
    ||
300  | 
    1, 3, 3, 5, 3, 2, 1, 1, 0, 8,  | 
    ||
301  | 
    1, 1, 1, 0, 1, 1, 0, 1, 0, 1,  | 
    ||
302  | 
    1, 0, 0, 0, 1, 2, 1, 2, 4, 2,  | 
    ||
303  | 
    4, 2, 4, 2, 4, 2, 4, 2, 3, 2,  | 
    ||
304  | 
    2, 2, 2, 2, 3, 0, 2, 0, 1, 1,  | 
    ||
305  | 
    1, 1, 1, 0, 7, 3, 2, 5, 5, 3,  | 
    ||
306  | 
    2, 1, 1, 3, 3, 2, 1, 0, 1, 1,  | 
    ||
307  | 
    1, 1, 1, 1, 0, 7, 3, 2, 4, 3,  | 
    ||
308  | 
    2, 2, 1, 1, 0, 1, 2, 0, 2, 0,  | 
    ||
309  | 
    3, 0, 1, 2, 1, 2, 2, 2, 3, 1,  | 
    ||
310  | 
    0, 2, 1, 1, 1, 0, 2, 0, 2, 1,  | 
    ||
311  | 
    0,  | 
    ||
312  | 
    };  | 
    ||
313  | 
    const short yydefred[] =  | 
    ||
314  | 
    	{                                      1, | 
    ||
315  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
316  | 
    23, 0, 0, 0, 3, 0, 0, 0, 0, 0,  | 
    ||
317  | 
    0, 0, 0, 0, 11, 12, 38, 46, 45, 39,  | 
    ||
318  | 
    41, 47, 184, 44, 0, 0, 64, 233, 40, 205,  | 
    ||
319  | 
    0, 0, 2, 4, 5, 6, 7, 8, 9, 10,  | 
    ||
320  | 
    0, 0, 240, 42, 0, 0, 0, 35, 96, 0,  | 
    ||
321  | 
    0, 63, 68, 0, 0, 67, 0, 0, 0, 0,  | 
    ||
322  | 
    0, 0, 66, 0, 0, 97, 237, 53, 60, 0,  | 
    ||
323  | 
    61, 0, 54, 0, 59, 0, 0, 57, 0, 0,  | 
    ||
324  | 
    192, 0, 0, 0, 0, 193, 0, 0, 230, 72,  | 
    ||
325  | 
    220, 73, 0, 0, 213, 0, 0, 0, 0, 214,  | 
    ||
326  | 
    0, 0, 99, 0, 0, 0, 62, 0, 0, 48,  | 
    ||
327  | 
    0, 50, 0, 191, 0, 0, 0, 185, 0, 187,  | 
    ||
328  | 
    0, 69, 0, 234, 0, 71, 235, 0, 0, 212,  | 
    ||
329  | 
    211, 206, 0, 208, 141, 142, 0, 13, 0, 14,  | 
    ||
330  | 
    143, 0, 110, 0, 0, 0, 109, 0, 56, 74,  | 
    ||
331  | 
    0, 55, 0, 49, 0, 190, 18, 0, 186, 0,  | 
    ||
332  | 
    0, 0, 0, 221, 223, 0, 0, 70, 210, 0,  | 
    ||
333  | 
    207, 0, 0, 0, 0, 115, 113, 0, 117, 0,  | 
    ||
334  | 
    105, 145, 146, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
335  | 
    138, 0, 137, 103, 100, 0, 102, 26, 27, 0,  | 
    ||
336  | 
    0, 0, 51, 239, 0, 0, 0, 0, 0, 197,  | 
    ||
337  | 
    0, 0, 227, 228, 226, 224, 209, 0, 0, 31,  | 
    ||
338  | 
    107, 119, 0, 116, 114, 118, 0, 0, 0, 148,  | 
    ||
339  | 
    0, 0, 0, 0, 126, 0, 130, 127, 136, 124,  | 
    ||
340  | 
    0, 0, 0, 0, 101, 0, 0, 0, 0, 0,  | 
    ||
341  | 
    ✓✗✗✓ | 
    2192  | 
    0, 79, 75, 0, 219, 33, 34, 188, 16, 0,  | 
    
342  | 
    0, 196, 0, 216, 0, 189, 229, 32, 0, 0,  | 
    ||
343  | 
    121, 120, 0, 106, 151, 150, 152, 133, 0, 135,  | 
    ||
344  | 
    125, 132, 129, 0, 104, 52, 86, 0, 0, 87,  | 
    ||
345  | 
    1096  | 
    19, 0, 88, 78, 81, 82, 201, 199, 200, 204,  | 
    |
346  | 
    1096  | 
    202, 203, 0, 80, 76, 195, 232, 194, 217, 108,  | 
    |
347  | 
    0, 111, 153, 0, 122, 92, 36, 37, 0, 0,  | 
    ||
348  | 
    1096  | 
    85, 83, 28, 139, 134, 0, 0, 0, 0, 0,  | 
    |
349  | 
    21, 0, 0, 90, 0, 0, 0, 0, 0, 0,  | 
    ||
350  | 
    0, 0, 0, 0, 0, 0, 140, 155, 0, 91,  | 
    ||
351  | 
    89, 93, 179, 180, 182, 183, 181, 0, 0, 0,  | 
    ||
352  | 
    0, 173, 158, 174, 171, 0, 0, 170, 172, 0,  | 
    ||
353  | 
    156, 0, 0, 175, 169, 0, 0, 0, 95, 94,  | 
    ||
354  | 
    0, 159, 177, 161, 163, 165, 167,  | 
    ||
355  | 
    };  | 
    ||
356  | 
    const short yydgoto[] =  | 
    ||
357  | 
    	{                                       1, | 
    ||
358  | 
    338, 213, 160, 384, 54, 302, 30, 241, 35, 313,  | 
    ||
359  | 
    203, 86, 272, 268, 127, 210, 16, 87, 152, 287,  | 
    ||
360  | 
    368, 262, 100, 101, 39, 344, 391, 161, 194, 332,  | 
    ||
361  | 
    88, 18, 19, 20, 21, 22, 23, 24, 154, 279,  | 
    ||
362  | 
    280, 135, 231, 329, 51, 70, 89, 90, 137, 65,  | 
    ||
363  | 
    56, 66, 103, 104, 263, 211, 264, 304, 76, 68,  | 
    ||
364  | 
    155, 156, 253, 254, 238, 239, 157, 323, 334, 357,  | 
    ||
365  | 
    339, 358, 359, 52, 97, 98, 221, 276, 57, 111,  | 
    ||
366  | 
    112, 174, 131, 175, 176,  | 
    ||
367  | 
    };  | 
    ||
368  | 
    const short yysindex[] =  | 
    ||
369  | 
    	{                                      0, | 
    ||
370  | 
    189, 36, -309, -301, -237, -293, -284, -275, -254, 66,  | 
    ||
371  | 
    0, -233, -211, 95, 0, -151, 151, 153, 158, 168,  | 
    ||
372  | 
    172, 175, 179, 182, 0, 0, 0, 0, 0, 0,  | 
    ||
373  | 
    0, 0, 0, 0, -168, -166, 0, 0, 0, 0,  | 
    ||
374  | 
    -161, -160, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
375  | 
    74, 80, 0, 0, 142, -111, 86, 0, 0, 200,  | 
    ||
376  | 
    200, 0, 0, 200, -111, 0, 200, 88, 200, 1005,  | 
    ||
377  | 
    841, -261, 0, -199, 4, 0, 0, 0, 0, -88,  | 
    ||
378  | 
    0, -118, 0, -61, 0, -117, -82, 0, 381, 200,  | 
    ||
379  | 
    0, -77, -131, -105, -102, 0, 936, 200, 0, 0,  | 
    ||
380  | 
    0, 0, 111, 32, 0, -81, -125, -107, -106, 0,  | 
    ||
381  | 
    -78, 200, 0, 1018, -103, -99, 0, 66, -97, 0,  | 
    ||
382  | 
    251, 0, -96, 0, -95, -280, -72, 0, 251, 0,  | 
    ||
383  | 
    -123, 0, 200, 0, -261, 0, 0, 66, 223, 0,  | 
    ||
384  | 
    1104  | 
    0, 0, 251, 0, 0, 0, 12, 0, 192, 0,  | 
    |
385  | 
    0, -207, 0, -119, -122, 200, 0, -302, 0, 0,  | 
    ||
386  | 
    1104  | 
    8, 0, 200, 0, -21, 0, 0, -52, 0, -48,  | 
    |
387  | 
    -76, -67, -60, 0, 0, -123, 0, 0, 0, -55,  | 
    ||
388  | 
    0, -112, -54, -51, -156, 0, 0, 41, 0, 181,  | 
    ||
389  | 
    0, 0, 0, 6, -220, -44, -294, -27, -22, -12,  | 
    ||
390  | 
    0, -244, 0, 0, 0, 251, 0, 0, 0, -21,  | 
    ||
391  | 
    ✓✗✗✓ | 
    2208  | 
    -217, -18, 0, 0, -263, -280, 51, 30, -21, 0,  | 
    
392  | 
    -137, -13, 0, 0, 0, 0, 0, 5, 38, 0,  | 
    ||
393  | 
    0, 0, -11, 0, 0, 0, 9, 33, 248, 0,  | 
    ||
394  | 
    -98, 13, 16, 23, 0, 27, 0, 0, 0, 0,  | 
    ||
395  | 
    31, 37, 33, 249, 0, 8, -197, 39, 26, 76,  | 
    ||
396  | 
    1104  | 
    -233, 0, 0, -217, 0, 0, 0, 0, 0, 30,  | 
    |
397  | 
    42, 0, 30, 0, 48, 0, 0, 0, 270, 33,  | 
    ||
398  | 
    1104  | 
    0, 0, 181, 0, 0, 0, 0, 0, 43, 0,  | 
    |
399  | 
    0, 0, 0, -244, 0, 0, 0, 49, -274, 0,  | 
    ||
400  | 
    0, 52, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
401  | 
    0, 0, 53, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
402  | 
    38, 0, 0, 54, 0, 0, 0, 0, 131, 136,  | 
    ||
403  | 
    0, 0, 0, 0, 0, 58, 62, -172, 1007, -280,  | 
    ||
404  | 
    0, 50, 64, 0, -219, 71, 97, -219, 72, 77,  | 
    ||
405  | 
    -265, -219, -219, 79, 84, -219, 0, 0, 1007, 0,  | 
    ||
406  | 
    0, 0, 0, 0, 0, 0, 0, 85, 146, 66,  | 
    ||
407  | 
    90, 0, 0, 0, 0, 93, 94, 0, 0, -251,  | 
    ||
408  | 
    0, 146, 98, 0, 0, 146, 146, 146, 0, 0,  | 
    ||
409  | 
    146, 0, 0, 0, 0, 0, 0,};  | 
    ||
410  | 
    const short yyrindex[] =  | 
    ||
411  | 
    	{                                      0, | 
    ||
412  | 
    132, 0, 0, 0, 0, 0, 0, 0, -8, 0,  | 
    ||
413  | 
    0, 0, 0, 140, 0, 0, 0, 0, 0, 0,  | 
    ||
414  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
415  | 
    0, 0, 0, 0, 447, 0, 0, 0, 0, 0,  | 
    ||
416  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
417  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 973,  | 
    ||
418  | 
    1048, 0, 0, -258, 449, 0, -165, 452, 911, 157,  | 
    ||
419  | 
    0, 0, 0, 0, 1033, 0, 0, 0, 0, 0,  | 
    ||
420  | 
    0, 0, 0, 0, 0, 0, 0, 0, 157, -101,  | 
    ||
421  | 
    0, 0, 0, 0, 126, 0, 0, 945, 0, 0,  | 
    ||
422  | 
    1104  | 
    0, 0, 0, -120, 0, 0, 0, 0, 0, 0,  | 
    |
423  | 
    1104  | 
    0, 201, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    |
424  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
425  | 
    -4, 0, -115, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
426  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
427  | 
    0, 262, 0, 0, 0, 819, 0, 160, 0, 0,  | 
    ||
428  | 
    399, 0, 911, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
429  | 
    0, 0, 0, 0, 0, -3, -110, 0, 0, 0,  | 
    ||
430  | 
    0, -1, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
431  | 
    0, 0, 0, 294, 0, 0, 0, 0, 128, 169,  | 
    ||
432  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
433  | 
    0, 0, 0, 0, 0, 850, 0, 21, 0, 0,  | 
    ||
434  | 
    852, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
435  | 
    0, 0, 0, 0, 0, 0, 0, 521, 0, 0,  | 
    ||
436  | 
    491, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
437  | 
    0, 0, -108, 0, 0, 399, 0, 0, 0, -9,  | 
    ||
438  | 
    0, 0, 0, 796, 0, 0, 0, 0, 0, 21,  | 
    ||
439  | 
    0, 0, 21, 0, 0, 0, 0, 0, 0, -109,  | 
    ||
440  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
441  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
442  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
443  | 
    0, 0, 369, 0, 0, 0, 0, 0, 0, 0,  | 
    ||
444  | 
    0, 0, 0, 0, 0, 0, 0, 0, 0, -162,  | 
    ||
445  | 
    0, 0, 0, 0, 0, 0, 0, 0, 281, 451,  | 
    ||
446  | 
    0, 0, 0, 0, 87, 0, 0, 87, 0, 0,  | 
    ||
447  | 
    0, 87, 87, 0, 0, 46, 0, 0, 478, 0,  | 
    ||
448  | 
    0, 0, 0, 0, 0, 0, 0, 556, 603, 0,  | 
    ||
449  | 
    635, 0, 0, 0, 0, 682, 714, 0, 0, 779,  | 
    ||
450  | 
    0, 603, 0, 0, 0, 603, 603, 603, 0, 0,  | 
    ||
451  | 
    603, 0, 0, 0, 0, 0, 0,};  | 
    ||
452  | 
    const short yygindex[] =  | 
    ||
453  | 
    	{                                      0, | 
    ||
454  | 
    0, 213, -10, -153, 0, 0, 0, 0, 0, 0,  | 
    ||
455  | 
    274, -34, -133, 134, 0, 0, 0, 0, 0, 0,  | 
    ||
456  | 
    -63, -136, 0, 368, 215, 104, 0, -84, 0, 0,  | 
    ||
457  | 
    20, 0, 0, 0, 0, 0, 0, 0, -113, 171,  | 
    ||
458  | 
    314, -187, 0, 0, 0, -31, 0, 409, -94, 0,  | 
    ||
459  | 
    0, 435, 373, 0, 247, 0, 0, 0, 0, 0,  | 
    ||
460  | 
    0, 357, 359, 220, 383, 234, 0, 0, 0, 0,  | 
    ||
461  | 
    0, 159, 0, 0, 0, 436, 0, 0, 0, 0,  | 
    ||
462  | 
    423, 0, 0, 362, 0,  | 
    ||
463  | 
    };  | 
    ||
464  | 
    #define YYTABLESIZE 1390  | 
    ||
465  | 
    const short yytable[] =  | 
    ||
466  | 
    	{                                      37, | 
    ||
467  | 
    198, 43, 205, 202, 238, 222, 225, 36, 30, 238,  | 
    ||
468  | 
    229, 64, 167, 69, 237, 29, 123, 195, 343, 28,  | 
    ||
469  | 
    17, 196, 3, 238, 374, 238, 164, 327, 216, 71,  | 
    ||
470  | 
    231, 246, 72, 208, 169, 74, 95, 77, 363, 222,  | 
    ||
471  | 
    225, 133, 163, 114, 364, 25, 142, 257, 181, 148,  | 
    ||
472  | 
    283, 258, 26, 179, 197, 178, 242, 150, 122, 209,  | 
    ||
473  | 
    365, 27, 95, 247, 248, 294, 130, 201, 375, 31,  | 
    ||
474  | 
    259, 105, 136, 256, 366, 134, 134, 32, 106, 260,  | 
    ||
475  | 
    144, 198, 273, 220, 3, 297, 33, 328, 34, 215,  | 
    ||
476  | 
    96, 102, 321, 110, 342, 367, 178, 343, 266, 267,  | 
    ||
477  | 
    99, 177, 269, 238, 20, 238, 29, 20, 192, 193,  | 
    ||
478  | 
    389, 255, 238, 199, 200, 198, 96, 201, 238, 261,  | 
    ||
479  | 
    222, 225, 107, 30, 207, 36, 298, 299, 113, 38,  | 
    ||
480  | 
    110, 214, 148, 153, 243, 244, 316, 131, 300, 318,  | 
    ||
481  | 
    150, 108, 195, 303, 234, 231, 196, 274, 275, 109,  | 
    ||
482  | 
    40, 145, 146, 236, 102, 41, 238, 236, 42, 63,  | 
    ||
483  | 
    43, 3, 44, 236, 301, 170, 235, 45, 238, 238,  | 
    ||
484  | 
    178, 131, 236, 239, 153, 238, 238, 46, 128, 197,  | 
    ||
485  | 
    171, 47, 238, 238, 48, 172, 285, 286, 49, 238,  | 
    ||
486  | 
    236, 50, 105, 53, 173, 55, 60, 147, 15, 106,  | 
    ||
487  | 
    58, 59, 61, 62, 238, 3, 198, 148, 67, 69,  | 
    ||
488  | 
    75, 178, 128, 149, 115, 150, 117, 236, 116, 228,  | 
    ||
489  | 
    238, 118, 236, 119, 238, 123, 269, 151, 392, 238,  | 
    ||
490  | 
    124, 125, 394, 395, 396, 132, 99, 397, 199, 200,  | 
    ||
491  | 
    238, 236, 201, 107, 126, 217, 238, 218, 238, 236,  | 
    ||
492  | 
    236, 239, 131, 236, 140, 198, 141, 138, 158, 198,  | 
    ||
493  | 
    163, 198, 108, 159, 162, 165, 168, 166, 198, 180,  | 
    ||
494  | 
    109, 144, 30, 30, 198, 198, 198, 198, 198, 222,  | 
    ||
495  | 
    225, 198, 30, 182, 371, 215, 223, 198, 376, 377,  | 
    ||
496  | 
    154, 231, 380, 128, 212, 224, 198, 198, 231, 222,  | 
    ||
497  | 
    198, 237, 225, 147, 231, 231, 231, 227, 232, 219,  | 
    ||
498  | 
    233, 231, 198, 178, 190, 178, 198, 245, 30, 178,  | 
    ||
499  | 
    178, 198, 178, 178, 240, 238, 178, 198, 30, 178,  | 
    ||
500  | 
    231, 198, 198, 250, 30, 178, 30, 251, 252, 198,  | 
    ||
501  | 
    198, 178, 231, 265, 178, 270, 231, 271, 30, 277,  | 
    ||
502  | 
    178, 281, 198, 43, 178, 307, 178, 222, 225, 385,  | 
    ||
503  | 
    178, 178, 231, 178, 178, 178, 278, 178, 308, 228,  | 
    ||
504  | 
    178, 282, 284, 295, 288, 178, 178, 289, 84, 178,  | 
    ||
505  | 
    178, 178, 178, 178, 290, 178, 144, 291, 306, 131,  | 
    ||
506  | 
    178, 178, 292, 131, 320, 178, 309, 178, 293, 324,  | 
    ||
507  | 
    305, 131, 131, 336, 317, 154, 178, 178, 218, 319,  | 
    ||
508  | 
    326, 131, 361, 330, 331, 335, 178, 337, 147, 340,  | 
    ||
509  | 
    178, 178, 178, 341, 178, 362, 131, 310, 311, 312,  | 
    ||
510  | 
    128, 178, 369, 372, 128, 370, 178, 383, 373, 183,  | 
    ||
511  | 
    378, 22, 128, 128, 2, 379, 382, 131, 178, 24,  | 
    ||
512  | 
    183, 386, 128, 131, 387, 388, 241, 131, 65, 393,  | 
    ||
513  | 
    15, 98, 58, 131, 17, 131, 25, 128, 296, 184,  | 
    ||
514  | 
    249, 238, 3, 360, 139, 314, 4, 131, 238, 185,  | 
    ||
515  | 
    184, 186, 5, 390, 238, 131, 131, 157, 128, 131,  | 
    ||
516  | 
    185, 333, 186, 84, 128, 230, 6, 121, 128, 73,  | 
    ||
517  | 
    149, 7, 8, 187, 128, 120, 128, 178, 188, 189,  | 
    ||
518  | 
    315, 206, 204, 325, 187, 9, 322, 381, 128, 188,  | 
    ||
519  | 
    189, 10, 238, 218, 11, 12, 128, 128, 13, 144,  | 
    ||
520  | 
    128, 191, 129, 143, 0, 144, 144, 226, 144, 144,  | 
    ||
521  | 
    0, 238, 144, 0, 0, 144, 144, 144, 0, 238,  | 
    ||
522  | 
    14, 144, 0, 0, 154, 154, 0, 144, 0, 0,  | 
    ||
523  | 
    144, 147, 0, 0, 154, 160, 144, 147, 147, 0,  | 
    ||
524  | 
    147, 147, 144, 0, 147, 15, 0, 147, 147, 147,  | 
    ||
525  | 
    144, 144, 0, 147, 0, 0, 0, 0, 0, 147,  | 
    ||
526  | 
    0, 144, 147, 0, 0, 144, 144, 144, 147, 144,  | 
    ||
527  | 
    154, 0, 157, 0, 147, 0, 144, 0, 0, 0,  | 
    ||
528  | 
    154, 144, 176, 147, 0, 149, 154, 0, 154, 0,  | 
    ||
529  | 
    0, 0, 0, 147, 0, 0, 0, 147, 147, 147,  | 
    ||
530  | 
    154, 147, 0, 84, 0, 0, 0, 84, 147, 84,  | 
    ||
531  | 
    0, 0, 0, 147, 162, 112, 84, 0, 0, 0,  | 
    ||
532  | 
    0, 78, 84, 84, 84, 84, 84, 0, 79, 84,  | 
    ||
533  | 
    0, 0, 0, 0, 3, 84, 0, 0, 0, 218,  | 
    ||
534  | 
    0, 80, 0, 0, 84, 84, 218, 0, 84, 0,  | 
    ||
535  | 
    160, 0, 218, 0, 0, 0, 0, 0, 0, 218,  | 
    ||
536  | 
    84, 164, 0, 0, 84, 0, 0, 0, 0, 84,  | 
    ||
537  | 
    0, 0, 81, 0, 218, 84, 82, 0, 0, 84,  | 
    ||
538  | 
    84, 83, 0, 0, 0, 15, 0, 84, 84, 15,  | 
    ||
539  | 
    218, 15, 84, 166, 218, 0, 0, 176, 15, 218,  | 
    ||
540  | 
    85, 0, 0, 0, 15, 15, 15, 15, 15, 0,  | 
    ||
541  | 
    218, 15, 0, 0, 0, 0, 0, 15, 218, 0,  | 
    ||
542  | 
    0, 157, 157, 0, 0, 0, 15, 15, 149, 162,  | 
    ||
543  | 
    15, 157, 0, 0, 149, 149, 0, 149, 149, 0,  | 
    ||
544  | 
    0, 149, 15, 0, 149, 0, 15, 0, 0, 236,  | 
    ||
545  | 
    149, 15, 0, 0, 0, 0, 149, 15, 168, 149,  | 
    ||
546  | 
    0, 15, 15, 0, 0, 149, 0, 157, 0, 15,  | 
    ||
547  | 
    15, 149, 0, 0, 0, 77, 164, 157, 0, 236,  | 
    ||
548  | 
    149, 0, 0, 157, 0, 157, 0, 0, 0, 236,  | 
    ||
549  | 
    149, 236, 0, 160, 149, 149, 149, 157, 149, 160,  | 
    ||
550  | 
    160, 0, 160, 160, 0, 149, 160, 0, 166, 160,  | 
    ||
551  | 
    149, 0, 0, 236, 0, 160, 0, 0, 236, 236,  | 
    ||
552  | 
    0, 160, 0, 0, 160, 0, 0, 0, 0, 15,  | 
    ||
553  | 
    160, 215, 0, 0, 0, 0, 160, 0, 0, 0,  | 
    ||
554  | 
    176, 0, 0, 0, 0, 160, 176, 176, 0, 176,  | 
    ||
555  | 
    176, 0, 0, 176, 0, 160, 176, 0, 0, 160,  | 
    ||
556  | 
    160, 160, 176, 160, 0, 0, 0, 0, 176, 0,  | 
    ||
557  | 
    160, 176, 162, 168, 0, 160, 0, 176, 162, 162,  | 
    ||
558  | 
    0, 162, 162, 176, 0, 162, 0, 0, 162, 0,  | 
    ||
559  | 
    77, 0, 176, 0, 162, 0, 0, 0, 0, 0,  | 
    ||
560  | 
    162, 0, 176, 162, 0, 0, 176, 176, 176, 162,  | 
    ||
561  | 
    176, 0, 0, 238, 0, 162, 0, 176, 0, 164,  | 
    ||
562  | 
    0, 0, 176, 0, 162, 164, 164, 0, 164, 164,  | 
    ||
563  | 
    0, 0, 164, 0, 162, 164, 0, 0, 162, 162,  | 
    ||
564  | 
    162, 164, 162, 0, 15, 0, 215, 164, 0, 162,  | 
    ||
565  | 
    164, 166, 0, 0, 162, 0, 164, 166, 166, 0,  | 
    ||
566  | 
    166, 166, 164, 0, 166, 0, 0, 166, 0, 0,  | 
    ||
567  | 
    0, 164, 0, 166, 0, 0, 0, 0, 0, 166,  | 
    ||
568  | 
    0, 164, 166, 0, 0, 164, 164, 164, 166, 164,  | 
    ||
569  | 
    0, 0, 0, 0, 166, 0, 164, 0, 0, 0,  | 
    ||
570  | 
    0, 164, 0, 166, 0, 238, 0, 0, 0, 0,  | 
    ||
571  | 
    0, 0, 0, 166, 0, 0, 168, 166, 166, 166,  | 
    ||
572  | 
    0, 166, 168, 168, 0, 168, 168, 0, 166, 168,  | 
    ||
573  | 
    128, 0, 168, 166, 0, 0, 77, 0, 168, 238,  | 
    ||
574  | 
    0, 0, 0, 77, 168, 0, 0, 168, 0, 77,  | 
    ||
575  | 
    77, 77, 77, 168, 0, 0, 77, 0, 0, 168,  | 
    ||
576  | 
    0, 0, 238, 238, 0, 0, 0, 0, 168, 0,  | 
    ||
577  | 
    0, 77, 238, 0, 0, 77, 0, 0, 168, 0,  | 
    ||
578  | 
    0, 91, 168, 168, 168, 0, 168, 77, 79, 0,  | 
    ||
579  | 
    15, 77, 215, 168, 3, 0, 77, 15, 168, 215,  | 
    ||
580  | 
    0, 92, 0, 15, 0, 215, 77, 77, 238, 0,  | 
    ||
581  | 
    15, 0, 215, 0, 77, 77, 0, 0, 238, 0,  | 
    ||
582  | 
    93, 0, 0, 0, 238, 0, 238, 0, 0, 15,  | 
    ||
583  | 
    0, 215, 81, 0, 0, 0, 94, 0, 238, 238,  | 
    ||
584  | 
    0, 15, 238, 215, 0, 15, 238, 215, 0, 0,  | 
    ||
585  | 
    0, 238, 84, 0, 238, 238, 0, 0, 238, 0,  | 
    ||
586  | 
    0, 15, 0, 215, 238, 0, 0, 0, 0, 238,  | 
    ||
587  | 
    0, 238, 0, 0, 0, 0, 91, 0, 0, 238,  | 
    ||
588  | 
    0, 238, 0, 79, 0, 238, 238, 0, 0, 3,  | 
    ||
589  | 
    238, 0, 238, 0, 0, 0, 92, 0, 238, 0,  | 
    ||
590  | 
    238, 0, 238, 238, 0, 238, 238, 0, 238, 238,  | 
    ||
591  | 
    238, 238, 238, 238, 0, 93, 238, 0, 238, 0,  | 
    ||
592  | 
    238, 238, 238, 0, 238, 0, 238, 81, 0, 238,  | 
    ||
593  | 
    238, 94, 0, 238, 0, 0, 238, 0, 238, 238,  | 
    ||
594  | 
    238, 0, 238, 0, 345, 78, 0, 84, 238, 0,  | 
    ||
595  | 
    0, 0, 79, 346, 347, 0, 238, 348, 3, 0,  | 
    ||
596  | 
    0, 145, 146, 0, 238, 80, 349, 0, 238, 0,  | 
    ||
597  | 
    0, 3, 350, 238, 0, 351, 238, 238, 0, 0,  | 
    ||
598  | 
    0, 352, 0, 0, 238, 0, 238, 353, 238, 0,  | 
    ||
599  | 
    0, 0, 238, 0, 0, 238, 81, 0, 0, 0,  | 
    ||
600  | 
    82, 238, 0, 0, 0, 83, 0, 147, 238, 0,  | 
    ||
601  | 
    354, 355, 0, 0, 0, 0, 84, 148, 0, 0,  | 
    ||
602  | 
    0, 356, 238, 149, 85, 150, 0, 238, 0, 0,  | 
    ||
603  | 
    0, 0, 238, 0, 0, 0, 0, 151, 238, 238,  | 
    ||
604  | 
    238, 0, 0, 238, 0, 0, 0, 0, 0, 0,  | 
    ||
605  | 
    0, 0, 238, 0, 0, 0, 0, 0, 0, 238,  | 
    ||
606  | 
    };  | 
    ||
607  | 
    const short yycheck[] =  | 
    ||
608  | 
    	{                                      10, | 
    ||
609  | 
    10, 10, 125, 123, 125, 10, 10, 60, 10, 125,  | 
    ||
610  | 
    548  | 
    123, 123, 126, 10, 125, 125, 125, 262, 270, 257,  | 
    |
611  | 
    548  | 
    1, 266, 284, 125, 290, 284, 121, 302, 165, 61,  | 
    |
612  | 
    10, 326, 64, 336, 129, 67, 71, 69, 258, 44,  | 
    ||
613  | 
    44, 10, 10, 75, 264, 10, 125, 265, 143, 330,  | 
    ||
614  | 
    238, 269, 362, 138, 299, 10, 277, 338, 90, 362,  | 
    ||
615  | 
    280, 363, 97, 358, 359, 253, 98, 362, 334, 363,  | 
    ||
616  | 
    ✗✓ | 24  | 
    288, 271, 104, 210, 294, 44, 44, 362, 278, 297,  | 
    
617  | 
    112, 326, 219, 168, 284, 283, 362, 362, 343, 307,  | 
    ||
618  | 
    71, 72, 280, 74, 267, 315, 10, 270, 362, 363,  | 
    ||
619  | 
    362, 133, 216, 362, 267, 271, 344, 270, 316, 317,  | 
    ||
620  | 
    362, 206, 278, 358, 359, 125, 97, 362, 284, 337,  | 
    ||
621  | 
    24  | 
    125, 125, 322, 125, 156, 60, 324, 325, 125, 363,  | 
    |
622  | 
    111, 163, 330, 114, 355, 356, 270, 10, 336, 273,  | 
    ||
623  | 
    24  | 
    338, 341, 262, 257, 301, 125, 266, 285, 286, 349,  | 
    |
624  | 
    362, 274, 275, 262, 135, 61, 322, 266, 310, 271,  | 
    ||
625  | 
    10, 284, 10, 284, 362, 289, 323, 10, 284, 271,  | 
    ||
626  | 
    125, 44, 329, 284, 155, 341, 278, 10, 10, 299,  | 
    ||
627  | 
    304, 10, 284, 349, 10, 309, 285, 286, 10, 291,  | 
    ||
628  | 
    ✓✓ | 16  | 
    299, 10, 271, 362, 318, 362, 123, 320, 10, 278,  | 
    
629  | 
    8  | 
    362, 362, 123, 62, 306, 284, 326, 330, 123, 10,  | 
    |
630  | 
    8  | 
    123, 125, 44, 336, 303, 338, 278, 326, 337, 332,  | 
    |
631  | 
    322, 339, 332, 306, 326, 303, 340, 350, 382, 331,  | 
    ||
632  | 
    362, 337, 386, 387, 388, 125, 362, 391, 358, 359,  | 
    ||
633  | 
    ✗✓ | 16  | 
    342, 362, 362, 322, 347, 298, 362, 300, 350, 358,  | 
    
634  | 
    359, 362, 125, 362, 362, 265, 363, 339, 362, 269,  | 
    ||
635  | 
    10, 271, 341, 363, 362, 362, 339, 363, 278, 47,  | 
    ||
636  | 
    ✗✓ | 8  | 
    349, 10, 274, 275, 284, 285, 286, 287, 288, 284,  | 
    
637  | 
    284, 291, 284, 272, 348, 307, 363, 297, 352, 353,  | 
    ||
638  | 
    10, 271, 356, 125, 287, 363, 306, 307, 278, 348,  | 
    ||
639  | 
    310, 261, 363, 10, 284, 285, 286, 363, 363, 362,  | 
    ||
640  | 
    362, 291, 322, 268, 123, 270, 326, 362, 320, 274,  | 
    ||
641  | 
    275, 331, 277, 278, 319, 125, 281, 337, 330, 284,  | 
    ||
642  | 
    ✗✓ | 8  | 
    310, 341, 342, 361, 336, 290, 338, 360, 351, 349,  | 
    
643  | 
    350, 296, 322, 362, 299, 295, 326, 318, 350, 363,  | 
    ||
644  | 
    305, 363, 362, 362, 268, 280, 311, 362, 362, 370,  | 
    ||
645  | 
    ✗✓ | 16  | 
    274, 275, 342, 277, 278, 320, 362, 281, 293, 332,  | 
    
646  | 
    8  | 
    284, 363, 125, 125, 362, 330, 290, 362, 10, 334,  | 
    |
647  | 
    335, 336, 296, 338, 362, 299, 125, 361, 363, 262,  | 
    ||
648  | 
    345, 305, 362, 266, 125, 350, 321, 311, 362, 357,  | 
    ||
649  | 
    362, 274, 275, 273, 363, 125, 320, 362, 10, 362,  | 
    ||
650  | 
    362, 284, 363, 362, 362, 362, 330, 282, 125, 362,  | 
    ||
651  | 
    8  | 
    334, 335, 336, 362, 338, 362, 299, 352, 353, 354,  | 
    |
652  | 
    262, 345, 362, 362, 266, 339, 350, 292, 362, 259,  | 
    ||
653  | 
    8  | 
    362, 310, 274, 275, 256, 362, 362, 320, 362, 310,  | 
    |
654  | 
    8  | 
    259, 362, 284, 326, 362, 362, 10, 330, 10, 362,  | 
    |
655  | 
    10, 10, 306, 336, 339, 338, 307, 299, 256, 289,  | 
    ||
656  | 
    8  | 
    197, 271, 284, 340, 107, 261, 288, 350, 278, 299,  | 
    |
657  | 
    8  | 
    289, 301, 294, 380, 284, 358, 359, 10, 320, 362,  | 
    |
658  | 
    8  | 
    299, 321, 301, 125, 326, 182, 308, 89, 330, 65,  | 
    |
659  | 
    ✗✓✓✓ | 
    8  | 
    10, 313, 314, 323, 336, 125, 338, 135, 328, 329,  | 
    
660  | 
    ✗✓ | 8  | 
    264, 155, 154, 294, 323, 327, 283, 359, 350, 328,  | 
    
661  | 
    329, 333, 322, 125, 336, 337, 358, 359, 340, 268,  | 
    ||
662  | 
    362, 149, 97, 111, -1, 274, 275, 176, 277, 278,  | 
    ||
663  | 
    -1, 341, 281, -1, -1, 284, 285, 286, -1, 349,  | 
    ||
664  | 
    362, 290, -1, -1, 274, 275, -1, 296, -1, -1,  | 
    ||
665  | 
    8  | 
    299, 268, -1, -1, 284, 10, 305, 274, 275, -1,  | 
    |
666  | 
    8  | 
    277, 278, 311, -1, 281, 125, -1, 284, 285, 286,  | 
    |
667  | 
    319, 320, -1, 290, -1, -1, -1, -1, -1, 296,  | 
    ||
668  | 
    8  | 
    -1, 330, 299, -1, -1, 334, 335, 336, 305, 338,  | 
    |
669  | 
    320, -1, 125, -1, 311, -1, 345, -1, -1, -1,  | 
    ||
670  | 
    330, 350, 10, 320, -1, 125, 336, -1, 338, -1,  | 
    ||
671  | 
    -1, -1, -1, 330, -1, -1, -1, 334, 335, 336,  | 
    ||
672  | 
    350, 338, -1, 265, -1, -1, -1, 269, 345, 271,  | 
    ||
673  | 
    -1, -1, -1, 350, 10, 125, 278, -1, -1, -1,  | 
    ||
674  | 
    -1, 271, 284, 285, 286, 287, 288, -1, 278, 291,  | 
    ||
675  | 
    -1, -1, -1, -1, 284, 297, -1, -1, -1, 271,  | 
    ||
676  | 
    -1, 291, -1, -1, 306, 307, 278, -1, 310, -1,  | 
    ||
677  | 
    125, -1, 284, -1, -1, -1, -1, -1, -1, 291,  | 
    ||
678  | 
    322, 10, -1, -1, 326, -1, -1, -1, -1, 331,  | 
    ||
679  | 
    -1, -1, 322, -1, 306, 337, 326, -1, -1, 341,  | 
    ||
680  | 
    342, 331, -1, -1, -1, 265, -1, 349, 350, 269,  | 
    ||
681  | 
    322, 271, 342, 10, 326, -1, -1, 125, 278, 331,  | 
    ||
682  | 
    350, -1, -1, -1, 284, 285, 286, 287, 288, -1,  | 
    ||
683  | 
    8  | 
    342, 291, -1, -1, -1, -1, -1, 297, 350, -1,  | 
    |
684  | 
    8  | 
    -1, 274, 275, -1, -1, -1, 306, 307, 268, 125,  | 
    |
685  | 
    8  | 
    310, 284, -1, -1, 274, 275, -1, 277, 278, -1,  | 
    |
686  | 
    -1, 281, 322, -1, 284, -1, 326, -1, -1, 259,  | 
    ||
687  | 
    8  | 
    290, 331, -1, -1, -1, -1, 296, 337, 10, 299,  | 
    |
688  | 
    -1, 341, 342, -1, -1, 305, -1, 320, -1, 349,  | 
    ||
689  | 
    350, 311, -1, -1, -1, 10, 125, 330, -1, 289,  | 
    ||
690  | 
    320, -1, -1, 336, -1, 338, -1, -1, -1, 299,  | 
    ||
691  | 
    330, 301, -1, 268, 334, 335, 336, 350, 338, 274,  | 
    ||
692  | 
    ✗✓ | 8  | 
    275, -1, 277, 278, -1, 345, 281, -1, 125, 284,  | 
    
693  | 
    350, -1, -1, 323, -1, 290, -1, -1, 328, 329,  | 
    ||
694  | 
    ✗✓ | 16  | 
    -1, 296, -1, -1, 299, -1, -1, -1, -1, 10,  | 
    
695  | 
    8  | 
    305, 10, -1, -1, -1, -1, 311, -1, -1, -1,  | 
    |
696  | 
    268, -1, -1, -1, -1, 320, 274, 275, -1, 277,  | 
    ||
697  | 
    278, -1, -1, 281, -1, 330, 284, -1, -1, 334,  | 
    ||
698  | 
    335, 336, 290, 338, -1, -1, -1, -1, 296, -1,  | 
    ||
699  | 
    345, 299, 268, 125, -1, 350, -1, 305, 274, 275,  | 
    ||
700  | 
    8  | 
    -1, 277, 278, 311, -1, 281, -1, -1, 284, -1,  | 
    |
701  | 
    8  | 
    125, -1, 320, -1, 290, -1, -1, -1, -1, -1,  | 
    |
702  | 
    8  | 
    296, -1, 330, 299, -1, -1, 334, 335, 336, 305,  | 
    |
703  | 
    8  | 
    338, -1, -1, 125, -1, 311, -1, 345, -1, 268,  | 
    |
704  | 
    ✗✓ | 8  | 
    -1, -1, 350, -1, 320, 274, 275, -1, 277, 278,  | 
    
705  | 
    -1, -1, 281, -1, 330, 284, -1, -1, 334, 335,  | 
    ||
706  | 
    ✗✓ | 8  | 
    336, 290, 338, -1, 125, -1, 125, 296, -1, 345,  | 
    
707  | 
    299, 268, -1, -1, 350, -1, 305, 274, 275, -1,  | 
    ||
708  | 
    277, 278, 311, -1, 281, -1, -1, 284, -1, -1,  | 
    ||
709  | 
    8  | 
    -1, 320, -1, 290, -1, -1, -1, -1, -1, 296,  | 
    |
710  | 
    ✗✓ | 8  | 
    -1, 330, 299, -1, -1, 334, 335, 336, 305, 338,  | 
    
711  | 
    -1, -1, -1, -1, 311, -1, 345, -1, -1, -1,  | 
    ||
712  | 
    8  | 
    -1, 350, -1, 320, -1, 125, -1, -1, -1, -1,  | 
    |
713  | 
    ✗✓ | 8  | 
    -1, -1, -1, 330, -1, -1, 268, 334, 335, 336,  | 
    
714  | 
    -1, 338, 274, 275, -1, 277, 278, -1, 345, 281,  | 
    ||
715  | 
    125, -1, 284, 350, -1, -1, 271, -1, 290, 125,  | 
    ||
716  | 
    -1, -1, -1, 278, 296, -1, -1, 299, -1, 284,  | 
    ||
717  | 
    285, 286, 287, 305, -1, -1, 291, -1, -1, 311,  | 
    ||
718  | 
    -1, -1, 274, 275, -1, -1, -1, -1, 320, -1,  | 
    ||
719  | 
    -1, 306, 284, -1, -1, 310, -1, -1, 330, -1,  | 
    ||
720  | 
    -1, 271, 334, 335, 336, -1, 338, 322, 278, -1,  | 
    ||
721  | 
    271, 326, 271, 345, 284, -1, 331, 278, 350, 278,  | 
    ||
722  | 
    ✗✓ | 8  | 
    -1, 291, -1, 284, -1, 284, 341, 342, 320, -1,  | 
    
723  | 
    291, -1, 291, -1, 349, 350, -1, -1, 330, -1,  | 
    ||
724  | 
    310, -1, -1, -1, 336, -1, 338, -1, -1, 310,  | 
    ||
725  | 
    -1, 310, 322, -1, -1, -1, 326, -1, 350, 259,  | 
    ||
726  | 
    8  | 
    -1, 322, 262, 322, -1, 326, 266, 326, -1, -1,  | 
    |
727  | 
    -1, 271, 342, -1, 274, 275, -1, -1, 278, -1,  | 
    ||
728  | 
    8  | 
    -1, 342, -1, 342, 284, -1, -1, -1, -1, 289,  | 
    |
729  | 
    -1, 291, -1, -1, -1, -1, 271, -1, -1, 299,  | 
    ||
730  | 
    -1, 301, -1, 278, -1, 271, 306, -1, -1, 284,  | 
    ||
731  | 
    310, -1, 278, -1, -1, -1, 291, -1, 284, -1,  | 
    ||
732  | 
    320, -1, 322, 323, -1, 291, 326, -1, 328, 329,  | 
    ||
733  | 
    330, 331, 332, 271, -1, 310, 336, -1, 338, -1,  | 
    ||
734  | 
    278, 341, 342, -1, 310, -1, 284, 322, -1, 349,  | 
    ||
735  | 
    350, 326, -1, 291, -1, -1, 322, -1, 358, 359,  | 
    ||
736  | 
    326, -1, 362, -1, 268, 271, -1, 342, 306, -1,  | 
    ||
737  | 
    -1, -1, 278, 277, 278, -1, 342, 281, 284, -1,  | 
    ||
738  | 
    -1, 274, 275, -1, 322, 291, 290, -1, 326, -1,  | 
    ||
739  | 
    -1, 284, 296, 331, -1, 299, 274, 275, -1, -1,  | 
    ||
740  | 
    -1, 305, -1, -1, 342, -1, 284, 311, 271, -1,  | 
    ||
741  | 
    -1, -1, 350, -1, -1, 278, 322, -1, -1, -1,  | 
    ||
742  | 
    326, 284, -1, -1, -1, 331, -1, 320, 291, -1,  | 
    ||
743  | 
    334, 335, -1, -1, -1, -1, 342, 330, -1, -1,  | 
    ||
744  | 
    -1, 345, 320, 336, 350, 338, -1, 310, -1, -1,  | 
    ||
745  | 
    -1, -1, 330, -1, -1, -1, -1, 350, 336, 322,  | 
    ||
746  | 
    338, -1, -1, 326, -1, -1, -1, -1, -1, -1,  | 
    ||
747  | 
    -1, -1, 350, -1, -1, -1, -1, -1, -1, 342,  | 
    ||
748  | 
    };  | 
    ||
749  | 
    #define YYFINAL 1  | 
    ||
750  | 
    #ifndef YYDEBUG  | 
    ||
751  | 
    #define YYDEBUG 0  | 
    ||
752  | 
    #endif  | 
    ||
753  | 
    #define YYMAXTOKEN 363  | 
    ||
754  | 
    #if YYDEBUG  | 
    ||
755  | 
    const char * const yyname[] =  | 
    ||
756  | 
    	{ | 
    ||
757  | 
    "end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  | 
    ||
758  | 
    0,0,0,0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,"'<'","'='",  | 
    ||
759  | 
    "'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  | 
    ||
760  | 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0, | 
    ||
761  | 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  | 
    ||
762  | 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  | 
    ||
763  | 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  | 
    ||
764  | 
    0,"ALL","APPEND","BACKLOG","BACKUP","BUFFER","CA","CACHE","SET","CHECK",  | 
    ||
765  | 
    "CIPHERS","CODE","COOKIE","DEMOTE","DIGEST","DISABLE","ERROR","EXPECT","PASS",  | 
    ||
766  | 
    "BLOCK","EXTERNAL","FILENAME","FORWARD","FROM","HASH","HEADER","HOST","ICMP",  | 
    ||
767  | 
    "INCLUDE","INET","INET6","INTERFACE","INTERVAL","IP","LABEL","LISTEN","VALUE",  | 
    ||
768  | 
    "LOADBALANCE","LOG","LOOKUP","METHOD","MODE","NAT","NO","DESTINATION","NODELAY",  | 
    ||
769  | 
    "NOTHING","ON","PARENT","PATH","PFTAG","PORT","PREFORK","PRIORITY","PROTO",  | 
    ||
770  | 
    "QUERYSTR","REAL","REDIRECT","RELAY","REMOVE","REQUEST","RESPONSE","RETRY",  | 
    ||
771  | 
    "QUICK","RETURN","ROUNDROBIN","ROUTE","SACK","SCRIPT","SEND","SESSION","SNMP",  | 
    ||
772  | 
    "SOCKET","SPLICE","SSL","STICKYADDR","STYLE","TABLE","TAG","TAGGED","TCP",  | 
    ||
773  | 
    "TIMEOUT","TLS","TO","ROUTER","RTLABEL","TRANSPARENT","TRAP","UPDATES","URL",  | 
    ||
774  | 
    "VIRTUAL","WITH","TTL","RTABLE","MATCH","PARAMS","RANDOM","LEASTSTATES",  | 
    ||
775  | 
    "SRCHASH","KEY","CERTIFICATE","PASSWORD","ECDH","EDH","CURVE","TICKETS",  | 
    ||
776  | 
    "STRING","NUMBER",  | 
    ||
777  | 
    };  | 
    ||
778  | 
    const char * const yyrule[] =  | 
    ||
779  | 
    	{"$accept : grammar", | 
    ||
780  | 
    "grammar :",  | 
    ||
781  | 
    "grammar : grammar include '\\n'",  | 
    ||
782  | 
    "grammar : grammar '\\n'",  | 
    ||
783  | 
    "grammar : grammar varset '\\n'",  | 
    ||
784  | 
    "grammar : grammar main '\\n'",  | 
    ||
785  | 
    "grammar : grammar rdr '\\n'",  | 
    ||
786  | 
    "grammar : grammar tabledef '\\n'",  | 
    ||
787  | 
    "grammar : grammar relay '\\n'",  | 
    ||
788  | 
    "grammar : grammar proto '\\n'",  | 
    ||
789  | 
    "grammar : grammar router '\\n'",  | 
    ||
790  | 
    "grammar : grammar error '\\n'",  | 
    ||
791  | 
    "include : INCLUDE STRING",  | 
    ||
792  | 
    "ssltls : SSL",  | 
    ||
793  | 
    "ssltls : TLS",  | 
    ||
794  | 
    "opttls :",  | 
    ||
795  | 
    "opttls : ssltls",  | 
    ||
796  | 
    "opttlsclient :",  | 
    ||
797  | 
    "opttlsclient : WITH ssltls",  | 
    ||
798  | 
    "http_type : STRING",  | 
    ||
799  | 
    "hostname :",  | 
    ||
800  | 
    "hostname : HOST STRING",  | 
    ||
801  | 
    "relay_proto :",  | 
    ||
802  | 
    "relay_proto : TCP",  | 
    ||
803  | 
    "relay_proto : STRING",  | 
    ||
804  | 
    "redirect_proto :",  | 
    ||
805  | 
    "redirect_proto : TCP",  | 
    ||
806  | 
    "redirect_proto : STRING",  | 
    ||
807  | 
    "eflags_l : eflags comma eflags_l",  | 
    ||
808  | 
    "eflags_l : eflags",  | 
    ||
809  | 
    "opteflags :",  | 
    ||
810  | 
    "opteflags : eflags",  | 
    ||
811  | 
    "eflags : STYLE STRING",  | 
    ||
812  | 
    "port : PORT STRING",  | 
    ||
813  | 
    "port : PORT NUMBER",  | 
    ||
814  | 
    "varset : STRING '=' STRING",  | 
    ||
815  | 
    "sendbuf : NOTHING",  | 
    ||
816  | 
    "sendbuf : STRING",  | 
    ||
817  | 
    "main : INTERVAL NUMBER",  | 
    ||
818  | 
    "main : LOG loglevel",  | 
    ||
819  | 
    "main : TIMEOUT timeout",  | 
    ||
820  | 
    "main : PREFORK NUMBER",  | 
    ||
821  | 
    "main : SNMP trap optstring",  | 
    ||
822  | 
    "trap :",  | 
    ||
823  | 
    "trap : TRAP",  | 
    ||
824  | 
    "loglevel : UPDATES",  | 
    ||
825  | 
    "loglevel : ALL",  | 
    ||
826  | 
    "$$1 :",  | 
    ||
827  | 
    "rdr : REDIRECT STRING $$1 '{' optnl rdropts_l '}'", | 
    ||
828  | 
    "rdropts_l : rdropts_l rdroptsl nl",  | 
    ||
829  | 
    "rdropts_l : rdroptsl optnl",  | 
    ||
830  | 
    "rdroptsl : forwardmode TO tablespec interface",  | 
    ||
831  | 
    "rdroptsl : LISTEN ON STRING redirect_proto port interface",  | 
    ||
832  | 
    "rdroptsl : DISABLE",  | 
    ||
833  | 
    "rdroptsl : STICKYADDR",  | 
    ||
834  | 
    "rdroptsl : match PFTAG STRING",  | 
    ||
835  | 
    "rdroptsl : SESSION TIMEOUT NUMBER",  | 
    ||
836  | 
    "rdroptsl : include",  | 
    ||
837  | 
    "match :",  | 
    ||
838  | 
    "match : MATCH",  | 
    ||
839  | 
    "forwardmode : FORWARD",  | 
    ||
840  | 
    "forwardmode : ROUTE",  | 
    ||
841  | 
    "forwardmode : TRANSPARENT FORWARD",  | 
    ||
842  | 
    "table : '<' STRING '>'",  | 
    ||
843  | 
    "$$2 :",  | 
    ||
844  | 
    "tabledef : TABLE table $$2 tabledefopts_l",  | 
    ||
845  | 
    "tabledefopts_l : tabledefopts_l tabledefopts",  | 
    ||
846  | 
    "tabledefopts_l : tabledefopts",  | 
    ||
847  | 
    "tabledefopts : DISABLE",  | 
    ||
848  | 
    "tabledefopts : '{' optnl tablelist_l '}'", | 
    ||
849  | 
    "tablelist_l : tablelist comma tablelist_l",  | 
    ||
850  | 
    "tablelist_l : tablelist optnl",  | 
    ||
851  | 
    "tablelist : host",  | 
    ||
852  | 
    "tablelist : include",  | 
    ||
853  | 
    "$$3 :",  | 
    ||
854  | 
    "tablespec : table $$3 tableopts_l",  | 
    ||
855  | 
    "tableopts_l : tableopts tableopts_l",  | 
    ||
856  | 
    "tableopts_l : tableopts",  | 
    ||
857  | 
    "tableopts : CHECK tablecheck",  | 
    ||
858  | 
    "tableopts : port",  | 
    ||
859  | 
    "tableopts : TIMEOUT timeout",  | 
    ||
860  | 
    "tableopts : DEMOTE STRING",  | 
    ||
861  | 
    "tableopts : INTERVAL NUMBER",  | 
    ||
862  | 
    "tableopts : MODE dstmode hashkey",  | 
    ||
863  | 
    "hashkey :",  | 
    ||
864  | 
    "hashkey : STRING",  | 
    ||
865  | 
    "tablecheck : ICMP",  | 
    ||
866  | 
    "tablecheck : TCP",  | 
    ||
867  | 
    "tablecheck : ssltls",  | 
    ||
868  | 
    "tablecheck : http_type STRING hostname CODE NUMBER",  | 
    ||
869  | 
    "tablecheck : http_type STRING hostname digest",  | 
    ||
870  | 
    "tablecheck : SEND sendbuf EXPECT STRING opttls",  | 
    ||
871  | 
    "tablecheck : SCRIPT STRING",  | 
    ||
872  | 
    "digest : DIGEST STRING",  | 
    ||
873  | 
    "optdigest : digest",  | 
    ||
874  | 
    "optdigest : STRING",  | 
    ||
875  | 
    "$$4 :",  | 
    ||
876  | 
    "proto : relay_proto PROTO STRING $$4 protopts_n",  | 
    ||
877  | 
    "protopts_n :",  | 
    ||
878  | 
    "protopts_n : '{' '}'", | 
    ||
879  | 
    "protopts_n : '{' optnl protopts_l '}'", | 
    ||
880  | 
    "protopts_l : protopts_l protoptsl nl",  | 
    ||
881  | 
    "protopts_l : protoptsl optnl",  | 
    ||
882  | 
    "protoptsl : ssltls tlsflags",  | 
    ||
883  | 
    "protoptsl : ssltls '{' tlsflags_l '}'", | 
    ||
884  | 
    "protoptsl : TCP tcpflags",  | 
    ||
885  | 
    "protoptsl : TCP '{' tcpflags_l '}'", | 
    ||
886  | 
    "protoptsl : RETURN ERROR opteflags",  | 
    ||
887  | 
    "protoptsl : RETURN ERROR '{' eflags_l '}'", | 
    ||
888  | 
    "protoptsl : filterrule",  | 
    ||
889  | 
    "protoptsl : include",  | 
    ||
890  | 
    "tcpflags_l : tcpflags comma tcpflags_l",  | 
    ||
891  | 
    "tcpflags_l : tcpflags",  | 
    ||
892  | 
    "tcpflags : SACK",  | 
    ||
893  | 
    "tcpflags : NO SACK",  | 
    ||
894  | 
    "tcpflags : NODELAY",  | 
    ||
895  | 
    "tcpflags : NO NODELAY",  | 
    ||
896  | 
    "tcpflags : SPLICE",  | 
    ||
897  | 
    "tcpflags : NO SPLICE",  | 
    ||
898  | 
    "tcpflags : BACKLOG NUMBER",  | 
    ||
899  | 
    "tcpflags : SOCKET BUFFER NUMBER",  | 
    ||
900  | 
    "tcpflags : IP STRING NUMBER",  | 
    ||
901  | 
    "tlsflags_l : tlsflags comma tlsflags_l",  | 
    ||
902  | 
    "tlsflags_l : tlsflags",  | 
    ||
903  | 
    "tlsflags : SESSION TICKETS",  | 
    ||
904  | 
    "tlsflags : NO SESSION TICKETS",  | 
    ||
905  | 
    "tlsflags : CIPHERS STRING",  | 
    ||
906  | 
    "tlsflags : NO EDH",  | 
    ||
907  | 
    "tlsflags : EDH",  | 
    ||
908  | 
    "tlsflags : EDH PARAMS STRING",  | 
    ||
909  | 
    "tlsflags : NO ECDH",  | 
    ||
910  | 
    "tlsflags : ECDH",  | 
    ||
911  | 
    "tlsflags : ECDH CURVE STRING",  | 
    ||
912  | 
    "tlsflags : CA FILENAME STRING",  | 
    ||
913  | 
    "tlsflags : CA KEY STRING PASSWORD STRING",  | 
    ||
914  | 
    "tlsflags : CA CERTIFICATE STRING",  | 
    ||
915  | 
    "tlsflags : NO flag",  | 
    ||
916  | 
    "tlsflags : flag",  | 
    ||
917  | 
    "flag : STRING",  | 
    ||
918  | 
    "$$5 :",  | 
    ||
919  | 
    "filterrule : action dir quick ruleaf rulesrc ruledst $$5 ruleopts_l",  | 
    ||
920  | 
    "action : PASS",  | 
    ||
921  | 
    "action : BLOCK",  | 
    ||
922  | 
    "action : MATCH",  | 
    ||
923  | 
    "dir :",  | 
    ||
924  | 
    "dir : REQUEST",  | 
    ||
925  | 
    "dir : RESPONSE",  | 
    ||
926  | 
    "quick :",  | 
    ||
927  | 
    "quick : QUICK",  | 
    ||
928  | 
    "ruleaf :",  | 
    ||
929  | 
    "ruleaf : INET6",  | 
    ||
930  | 
    "ruleaf : INET",  | 
    ||
931  | 
    "rulesrc :",  | 
    ||
932  | 
    "ruledst :",  | 
    ||
933  | 
    "ruleopts_l :",  | 
    ||
934  | 
    "ruleopts_l : ruleopts_t",  | 
    ||
935  | 
    "ruleopts_t : ruleopts ruleopts_t",  | 
    ||
936  | 
    "ruleopts_t : ruleopts",  | 
    ||
937  | 
    ✓✗✓ | 16  | 
    "ruleopts : METHOD STRING",  | 
    
938  | 
    "ruleopts : COOKIE key_option STRING value",  | 
    ||
939  | 
    "ruleopts : COOKIE key_option",  | 
    ||
940  | 
    8  | 
    "ruleopts : HEADER key_option STRING value",  | 
    |
941  | 
    "ruleopts : HEADER key_option",  | 
    ||
942  | 
    "ruleopts : PATH key_option STRING value",  | 
    ||
943  | 
    "ruleopts : PATH key_option",  | 
    ||
944  | 
    "ruleopts : QUERYSTR key_option STRING value",  | 
    ||
945  | 
    "ruleopts : QUERYSTR key_option",  | 
    ||
946  | 
    "ruleopts : URL key_option optdigest value",  | 
    ||
947  | 
    "ruleopts : URL key_option",  | 
    ||
948  | 
    "ruleopts : FORWARD TO table",  | 
    ||
949  | 
    8  | 
    "ruleopts : TAG STRING",  | 
    |
950  | 
    "ruleopts : NO TAG",  | 
    ||
951  | 
    8  | 
    "ruleopts : TAGGED STRING",  | 
    |
952  | 
    "ruleopts : LABEL STRING",  | 
    ||
953  | 
    "ruleopts : NO LABEL",  | 
    ||
954  | 
    8  | 
    "ruleopts : FILENAME STRING value",  | 
    |
955  | 
    8  | 
    "value :",  | 
    |
956  | 
    "value : VALUE STRING",  | 
    ||
957  | 
    8  | 
    "key_option :",  | 
    |
958  | 
    24  | 
    "key_option : APPEND",  | 
    |
959  | 
    24  | 
    "key_option : SET",  | 
    |
960  | 
    "key_option : REMOVE",  | 
    ||
961  | 
    24  | 
    "key_option : HASH",  | 
    |
962  | 
    "key_option : LOG",  | 
    ||
963  | 
    "$$6 :",  | 
    ||
964  | 
    "relay : RELAY STRING $$6 '{' optnl relayopts_l '}'", | 
    ||
965  | 
    "relayopts_l : relayopts_l relayoptsl nl",  | 
    ||
966  | 
    ✓✓ | 1088  | 
    "relayopts_l : relayoptsl optnl",  | 
    
967  | 
    540  | 
    "relayoptsl : LISTEN ON STRING port opttls",  | 
    |
968  | 
    540  | 
    "relayoptsl : forwardmode opttlsclient TO forwardspec dstaf",  | 
    |
969  | 
    "relayoptsl : SESSION TIMEOUT NUMBER",  | 
    ||
970  | 
    "relayoptsl : PROTO STRING",  | 
    ||
971  | 
    ✗✓ | 548  | 
    "relayoptsl : DISABLE",  | 
    
972  | 
    "relayoptsl : include",  | 
    ||
973  | 
    "forwardspec : STRING port retry",  | 
    ||
974  | 
    ✗✓ | 1096  | 
    "forwardspec : NAT LOOKUP retry",  | 
    
975  | 
    "forwardspec : DESTINATION retry",  | 
    ||
976  | 
    "forwardspec : tablespec",  | 
    ||
977  | 
    "dstmode :",  | 
    ||
978  | 
    ✗✓ | 548  | 
    "dstmode : LOADBALANCE",  | 
    
979  | 
    "dstmode : ROUNDROBIN",  | 
    ||
980  | 
    "dstmode : HASH",  | 
    ||
981  | 
    "dstmode : LEASTSTATES",  | 
    ||
982  | 
    "dstmode : SRCHASH",  | 
    ||
983  | 
    ✗✓ | 548  | 
    "dstmode : RANDOM",  | 
    
984  | 
    "$$7 :",  | 
    ||
985  | 
    "router : ROUTER STRING $$7 '{' optnl routeopts_l '}'", | 
    ||
986  | 
    ✗✓ | 548  | 
    "routeopts_l : routeopts_l routeoptsl nl",  | 
    
987  | 
    "routeopts_l : routeoptsl optnl",  | 
    ||
988  | 
    "routeoptsl : ROUTE address '/' NUMBER",  | 
    ||
989  | 
    "routeoptsl : FORWARD TO tablespec",  | 
    ||
990  | 
    "routeoptsl : RTABLE NUMBER",  | 
    ||
991  | 
    "routeoptsl : RTLABEL STRING",  | 
    ||
992  | 
    "routeoptsl : DISABLE",  | 
    ||
993  | 
    548  | 
    "routeoptsl : include",  | 
    |
994  | 
    548  | 
    "dstaf :",  | 
    |
995  | 
    548  | 
    "dstaf : INET",  | 
    |
996  | 
    548  | 
    "dstaf : INET6 STRING",  | 
    |
997  | 
    548  | 
    "interface :",  | 
    |
998  | 
    548  | 
    "interface : INTERFACE STRING",  | 
    |
999  | 
    548  | 
    "$$8 :",  | 
    |
1000  | 
    548  | 
    "host : address $$8 opthostflags",  | 
    |
1001  | 
    "opthostflags :",  | 
    ||
1002  | 
    548  | 
    "opthostflags : hostflags_l",  | 
    |
1003  | 
    "hostflags_l : hostflags hostflags_l",  | 
    ||
1004  | 
    548  | 
    "hostflags_l : hostflags",  | 
    |
1005  | 
    "hostflags : RETRY NUMBER",  | 
    ||
1006  | 
    ✗✓ | 548  | 
    "hostflags : PARENT NUMBER",  | 
    
1007  | 
    "hostflags : PRIORITY NUMBER",  | 
    ||
1008  | 
    "hostflags : IP TTL NUMBER",  | 
    ||
1009  | 
    "address : STRING",  | 
    ||
1010  | 
    "retry :",  | 
    ||
1011  | 
    548  | 
    "retry : RETRY NUMBER",  | 
    |
1012  | 
    ✗✓✓✓ | 
    548  | 
    "timeout : NUMBER",  | 
    
1013  | 
    548  | 
    "comma : ','",  | 
    |
1014  | 
    "comma : nl",  | 
    ||
1015  | 
    ✗✓ | 548  | 
    "comma :",  | 
    
1016  | 
    "optnl : '\\n' optnl",  | 
    ||
1017  | 
    "optnl :",  | 
    ||
1018  | 
    "nl : '\\n' optnl",  | 
    ||
1019  | 
    "optstring : STRING",  | 
    ||
1020  | 
    548  | 
    "optstring :",  | 
    |
1021  | 
    };  | 
    ||
1022  | 
    548  | 
    #endif  | 
    |
1023  | 
    #ifdef YYSTACKSIZE  | 
    ||
1024  | 
    #undef YYMAXDEPTH  | 
    ||
1025  | 
    #define YYMAXDEPTH YYSTACKSIZE  | 
    ||
1026  | 
    #else  | 
    ||
1027  | 
    #ifdef YYMAXDEPTH  | 
    ||
1028  | 
    #define YYSTACKSIZE YYMAXDEPTH  | 
    ||
1029  | 
    #else  | 
    ||
1030  | 
    #define YYSTACKSIZE 10000  | 
    ||
1031  | 
    #define YYMAXDEPTH 10000  | 
    ||
1032  | 
    #endif  | 
    ||
1033  | 
    #endif  | 
    ||
1034  | 
    #define YYINITSTACKSIZE 200  | 
    ||
1035  | 
    /* LINTUSED */  | 
    ||
1036  | 
    int yydebug;  | 
    ||
1037  | 
    64  | 
    int yynerrs;  | 
    |
1038  | 
    64  | 
    int yyerrflag;  | 
    |
1039  | 
    int yychar;  | 
    ||
1040  | 
    short *yyssp;  | 
    ||
1041  | 
    YYSTYPE *yyvsp;  | 
    ||
1042  | 
    YYSTYPE yyval;  | 
    ||
1043  | 
    YYSTYPE yylval;  | 
    ||
1044  | 
    short *yyss;  | 
    ||
1045  | 
    short *yysslim;  | 
    ||
1046  | 
    YYSTYPE *yyvs;  | 
    ||
1047  | 
    unsigned int yystacksize;  | 
    ||
1048  | 
    int yyparse(void);  | 
    ||
1049  | 
    #line 2152 "parse.y"  | 
    ||
1050  | 
    |||
1051  | 
    struct keywords { | 
    ||
1052  | 
    276  | 
    const char *k_name;  | 
    |
1053  | 
    276  | 
    int k_val;  | 
    |
1054  | 
    };  | 
    ||
1055  | 
    |||
1056  | 
    int  | 
    ||
1057  | 
    yyerror(const char *fmt, ...)  | 
    ||
1058  | 
    { | 
    ||
1059  | 
    va_list ap;  | 
    ||
1060  | 
    char *msg;  | 
    ||
1061  | 
    8  | 
    ||
1062  | 
    ✗✓ | 8  | 
    file->errors++;  | 
    
1063  | 
    va_start(ap, fmt);  | 
    ||
1064  | 
    if (vasprintf(&msg, fmt, ap) == -1)  | 
    ||
1065  | 
    		fatalx("yyerror vasprintf"); | 
    ||
1066  | 
    va_end(ap);  | 
    ||
1067  | 
    logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);  | 
    ||
1068  | 
    free(msg);  | 
    ||
1069  | 
    return (0);  | 
    ||
1070  | 
    }  | 
    ||
1071  | 
    |||
1072  | 
    int  | 
    ||
1073  | 
    kw_cmp(const void *k, const void *e)  | 
    ||
1074  | 
    { | 
    ||
1075  | 
    return (strcmp(k, ((const struct keywords *)e)->k_name));  | 
    ||
1076  | 
    }  | 
    ||
1077  | 
    |||
1078  | 
    int  | 
    ||
1079  | 
    lookup(char *s)  | 
    ||
1080  | 
    { | 
    ||
1081  | 
    /* this has to be sorted always */  | 
    ||
1082  | 
    	static const struct keywords keywords[] = { | 
    ||
1083  | 
    		{ "all",		ALL }, | 
    ||
1084  | 
    		{ "append",		APPEND }, | 
    ||
1085  | 
    		{ "backlog",		BACKLOG }, | 
    ||
1086  | 
    		{ "backup",		BACKUP }, | 
    ||
1087  | 
    		{ "block",		BLOCK }, | 
    ||
1088  | 
    		{ "buffer",		BUFFER }, | 
    ||
1089  | 
    		{ "ca",			CA }, | 
    ||
1090  | 
    		{ "cache",		CACHE }, | 
    ||
1091  | 
    		{ "cert",		CERTIFICATE }, | 
    ||
1092  | 
    		{ "check",		CHECK }, | 
    ||
1093  | 
    		{ "ciphers",		CIPHERS }, | 
    ||
1094  | 
    		{ "code",		CODE }, | 
    ||
1095  | 
    		{ "cookie",		COOKIE }, | 
    ||
1096  | 
    		{ "curve",		CURVE }, | 
    ||
1097  | 
    		{ "demote",		DEMOTE }, | 
    ||
1098  | 
    		{ "destination",	DESTINATION }, | 
    ||
1099  | 
    		{ "digest",		DIGEST }, | 
    ||
1100  | 
    		{ "disable",		DISABLE }, | 
    ||
1101  | 
    		{ "ecdh",		ECDH }, | 
    ||
1102  | 
    		{ "edh",		EDH }, | 
    ||
1103  | 
    		{ "error",		ERROR }, | 
    ||
1104  | 
    		{ "expect",		EXPECT }, | 
    ||
1105  | 
    		{ "external",		EXTERNAL }, | 
    ||
1106  | 
    		{ "file",		FILENAME }, | 
    ||
1107  | 
    		{ "forward",		FORWARD }, | 
    ||
1108  | 
    		{ "from",		FROM }, | 
    ||
1109  | 
    		{ "hash",		HASH }, | 
    ||
1110  | 
    		{ "header",		HEADER }, | 
    ||
1111  | 
    		{ "host",		HOST }, | 
    ||
1112  | 
    		{ "icmp",		ICMP }, | 
    ||
1113  | 
    		{ "include",		INCLUDE }, | 
    ||
1114  | 
    		{ "inet",		INET }, | 
    ||
1115  | 
    		{ "inet6",		INET6 }, | 
    ||
1116  | 
    		{ "interface",		INTERFACE }, | 
    ||
1117  | 
    		{ "interval",		INTERVAL }, | 
    ||
1118  | 
    		{ "ip",			IP }, | 
    ||
1119  | 
    		{ "key",		KEY }, | 
    ||
1120  | 
    		{ "label",		LABEL }, | 
    ||
1121  | 
    		{ "least-states",	LEASTSTATES }, | 
    ||
1122  | 
    		{ "listen",		LISTEN }, | 
    ||
1123  | 
    		{ "loadbalance",	LOADBALANCE }, | 
    ||
1124  | 
    		{ "log",		LOG }, | 
    ||
1125  | 
    		{ "lookup",		LOOKUP }, | 
    ||
1126  | 
    		{ "match",		MATCH }, | 
    ||
1127  | 
    		{ "method",		METHOD }, | 
    ||
1128  | 
    		{ "mode",		MODE }, | 
    ||
1129  | 
    		{ "nat",		NAT }, | 
    ||
1130  | 
    		{ "no",			NO }, | 
    ||
1131  | 
    		{ "nodelay",		NODELAY }, | 
    ||
1132  | 
    		{ "nothing",		NOTHING }, | 
    ||
1133  | 
    		{ "on",			ON }, | 
    ||
1134  | 
    		{ "params",		PARAMS }, | 
    ||
1135  | 
    		{ "parent",		PARENT }, | 
    ||
1136  | 
    		{ "pass",		PASS }, | 
    ||
1137  | 
    		{ "password",		PASSWORD }, | 
    ||
1138  | 
    		{ "path",		PATH }, | 
    ||
1139  | 
    		{ "pftag",		PFTAG }, | 
    ||
1140  | 
    		{ "port",		PORT }, | 
    ||
1141  | 
    		{ "prefork",		PREFORK }, | 
    ||
1142  | 
    		{ "priority",		PRIORITY }, | 
    ||
1143  | 
    		{ "protocol",		PROTO }, | 
    ||
1144  | 
    		{ "query",		QUERYSTR }, | 
    ||
1145  | 
    		{ "quick",		QUICK }, | 
    ||
1146  | 
    		{ "random",		RANDOM }, | 
    ||
1147  | 
    		{ "real",		REAL }, | 
    ||
1148  | 
    		{ "redirect",		REDIRECT }, | 
    ||
1149  | 
    		{ "relay",		RELAY }, | 
    ||
1150  | 
    		{ "remove",		REMOVE }, | 
    ||
1151  | 
    		{ "request",		REQUEST }, | 
    ||
1152  | 
    		{ "response",		RESPONSE }, | 
    ||
1153  | 
    		{ "retry",		RETRY }, | 
    ||
1154  | 
    		{ "return",		RETURN }, | 
    ||
1155  | 
    		{ "roundrobin",		ROUNDROBIN }, | 
    ||
1156  | 
    		{ "route",		ROUTE }, | 
    ||
1157  | 
    		{ "router",		ROUTER }, | 
    ||
1158  | 
    		{ "rtable",		RTABLE }, | 
    ||
1159  | 
    		{ "rtlabel",		RTLABEL }, | 
    ||
1160  | 
    		{ "sack",		SACK }, | 
    ||
1161  | 
    		{ "script",		SCRIPT }, | 
    ||
1162  | 
    		{ "send",		SEND }, | 
    ||
1163  | 
    		{ "session",		SESSION }, | 
    ||
1164  | 
    		{ "set",		SET }, | 
    ||
1165  | 
    		{ "snmp",		SNMP }, | 
    ||
1166  | 
    		{ "socket",		SOCKET }, | 
    ||
1167  | 
    		{ "source-hash",	SRCHASH }, | 
    ||
1168  | 
    		{ "splice",		SPLICE }, | 
    ||
1169  | 
    		{ "ssl",		SSL }, | 
    ||
1170  | 
    		{ "sticky-address",	STICKYADDR }, | 
    ||
1171  | 
    		{ "style",		STYLE }, | 
    ||
1172  | 
    		{ "table",		TABLE }, | 
    ||
1173  | 
    		{ "tag",		TAG }, | 
    ||
1174  | 
    		{ "tagged",		TAGGED }, | 
    ||
1175  | 
    		{ "tcp",		TCP }, | 
    ||
1176  | 
    		{ "tickets",		TICKETS }, | 
    ||
1177  | 
    		{ "timeout",		TIMEOUT }, | 
    ||
1178  | 
    		{ "tls",		TLS }, | 
    ||
1179  | 
    ✗✓ | 32  | 
    		{ "to",			TO }, | 
    
1180  | 
    16  | 
    		{ "transparent",	TRANSPARENT }, | 
    |
1181  | 
    		{ "trap",		TRAP }, | 
    ||
1182  | 
    		{ "ttl",		TTL }, | 
    ||
1183  | 
    		{ "updates",		UPDATES }, | 
    ||
1184  | 
    		{ "url",		URL }, | 
    ||
1185  | 
    		{ "value",		VALUE }, | 
    ||
1186  | 
    		{ "virtual",		VIRTUAL }, | 
    ||
1187  | 
    ✗✓ | 16  | 
    		{ "with",		WITH } | 
    
1188  | 
    };  | 
    ||
1189  | 
    const struct keywords *p;  | 
    ||
1190  | 
    |||
1191  | 
    p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),  | 
    ||
1192  | 
    sizeof(keywords[0]), kw_cmp);  | 
    ||
1193  | 
    16  | 
    ||
1194  | 
    16  | 
    if (p)  | 
    |
1195  | 
    return (p->k_val);  | 
    ||
1196  | 
    16  | 
    else  | 
    |
1197  | 
    ✗✓ | 32  | 
    return (STRING);  | 
    
1198  | 
    16  | 
    }  | 
    |
1199  | 
    |||
1200  | 
    #define MAXPUSHBACK 128  | 
    ||
1201  | 
    |||
1202  | 
    u_char *parsebuf;  | 
    ||
1203  | 
    int parseindex;  | 
    ||
1204  | 
    16  | 
    u_char pushback_buffer[MAXPUSHBACK];  | 
    |
1205  | 
    int pushback_index = 0;  | 
    ||
1206  | 
    16  | 
    ||
1207  | 
    int  | 
    ||
1208  | 
    lgetc(int quotec)  | 
    ||
1209  | 
    { | 
    ||
1210  | 
    int c, next;  | 
    ||
1211  | 
    |||
1212  | 
    	if (parsebuf) { | 
    ||
1213  | 
    /* Read character from the parsebuffer instead of input. */  | 
    ||
1214  | 
    		if (parseindex >= 0) { | 
    ||
1215  | 
    c = parsebuf[parseindex++];  | 
    ||
1216  | 
    if (c != '\0')  | 
    ||
1217  | 
    return (c);  | 
    ||
1218  | 
    parsebuf = NULL;  | 
    ||
1219  | 
    } else  | 
    ||
1220  | 
    parseindex++;  | 
    ||
1221  | 
    }  | 
    ||
1222  | 
    |||
1223  | 
    if (pushback_index)  | 
    ||
1224  | 
    return (pushback_buffer[--pushback_index]);  | 
    ||
1225  | 
    |||
1226  | 
    	if (quotec) { | 
    ||
1227  | 
    		if ((c = getc(file->stream)) == EOF) { | 
    ||
1228  | 
    			yyerror("reached end of file while parsing " | 
    ||
1229  | 
    "quoted string");  | 
    ||
1230  | 
    if (file == topfile || popfile() == EOF)  | 
    ||
1231  | 
    return (EOF);  | 
    ||
1232  | 
    return (quotec);  | 
    ||
1233  | 
    }  | 
    ||
1234  | 
    return (c);  | 
    ||
1235  | 
    ✗✓ | 804  | 
    }  | 
    
1236  | 
    |||
1237  | 
    	while ((c = getc(file->stream)) == '\\') { | 
    ||
1238  | 
    804  | 
    next = getc(file->stream);  | 
    |
1239  | 
    804  | 
    		if (next != '\n') { | 
    |
1240  | 
    804  | 
    c = next;  | 
    |
1241  | 
    804  | 
    break;  | 
    |
1242  | 
    804  | 
    }  | 
    |
1243  | 
    yylval.lineno = file->lineno;  | 
    ||
1244  | 
    804  | 
    file->lineno++;  | 
    |
1245  | 
    }  | 
    ||
1246  | 
    ✗✓ | 1608  | 
    |
1247  | 
    	while (c == EOF) { | 
    ||
1248  | 
    if (file == topfile || popfile() == EOF)  | 
    ||
1249  | 
    return (EOF);  | 
    ||
1250  | 
    c = getc(file->stream);  | 
    ||
1251  | 
    }  | 
    ||
1252  | 
    return (c);  | 
    ||
1253  | 
    }  | 
    ||
1254  | 
    |||
1255  | 
    int  | 
    ||
1256  | 
    lungetc(int c)  | 
    ||
1257  | 
    { | 
    ||
1258  | 
    ✓✓ | 804  | 
    if (c == EOF)  | 
    
1259  | 
    8  | 
    return (EOF);  | 
    |
1260  | 
    804  | 
    	if (parsebuf) { | 
    |
1261  | 
    804  | 
    parseindex--;  | 
    |
1262  | 
    804  | 
    if (parseindex >= 0)  | 
    |
1263  | 
    return (c);  | 
    ||
1264  | 
    804  | 
    }  | 
    |
1265  | 
    if (pushback_index < MAXPUSHBACK-1)  | 
    ||
1266  | 
    56  | 
    return (pushback_buffer[pushback_index++] = c);  | 
    |
1267  | 
    184  | 
    else  | 
    |
1268  | 
    748  | 
    return (EOF);  | 
    |
1269  | 
    620  | 
    }  | 
    |
1270  | 
    |||
1271  | 
    int  | 
    ||
1272  | 
    64  | 
    findeol(void)  | 
    |
1273  | 
    { | 
    ||
1274  | 
    64  | 
    int c;  | 
    |
1275  | 
    510  | 
    ||
1276  | 
    parsebuf = NULL;  | 
    ||
1277  | 
    510  | 
    ||
1278  | 
    230  | 
    /* skip to either EOF or the first real EOL */  | 
    |
1279  | 
    	while (1) { | 
    ||
1280  | 
    230  | 
    if (pushback_index)  | 
    |
1281  | 
    c = pushback_buffer[--pushback_index];  | 
    ||
1282  | 
    796  | 
    else  | 
    |
1283  | 
    804  | 
    c = lgetc(0);  | 
    |
1284  | 
    8  | 
    		if (c == '\n') { | 
    |
1285  | 
    file->lineno++;  | 
    ||
1286  | 
    804  | 
    break;  | 
    |
1287  | 
    804  | 
    }  | 
    |
1288  | 
    if (c == EOF)  | 
    ||
1289  | 
    break;  | 
    ||
1290  | 
    }  | 
    ||
1291  | 
    return (ERROR);  | 
    ||
1292  | 
    }  | 
    ||
1293  | 
    |||
1294  | 
    int  | 
    ||
1295  | 
    yylex(void)  | 
    ||
1296  | 
    { | 
    ||
1297  | 
    u_char buf[8096];  | 
    ||
1298  | 
    u_char *p, *val;  | 
    ||
1299  | 
    int quotec, next, c;  | 
    ||
1300  | 
    int token;  | 
    ||
1301  | 
    |||
1302  | 
    top:  | 
    ||
1303  | 
    p = buf;  | 
    ||
1304  | 
    while ((c = lgetc(0)) == ' ' || c == '\t')  | 
    ||
1305  | 
    ; /* nothing */  | 
    ||
1306  | 
    |||
1307  | 
    ✗✓ | 8  | 
    yylval.lineno = file->lineno;  | 
    
1308  | 
    if (c == '#')  | 
    ||
1309  | 
    while ((c = lgetc(0)) != '\n' && c != EOF)  | 
    ||
1310  | 
    ; /* nothing */  | 
    ||
1311  | 
    	if (c == '$' && parsebuf == NULL) { | 
    ||
1312  | 
    		while (1) { | 
    ||
1313  | 
    if ((c = lgetc(0)) == EOF)  | 
    ||
1314  | 
    8  | 
    return (0);  | 
    |
1315  | 
    8  | 
    ||
1316  | 
    ✗✓ | 8  | 
    			if (p + 1 >= buf + sizeof(buf) - 1) { | 
    
1317  | 
    				yyerror("string too long"); | 
    ||
1318  | 
    24  | 
    return (findeol());  | 
    |
1319  | 
    24  | 
    }  | 
    |
1320  | 
    24  | 
    			if (isalnum(c) || c == '_') { | 
    |
1321  | 
    ✓✗ | 72  | 
    *p++ = c;  | 
    
1322  | 
    24  | 
    continue;  | 
    |
1323  | 
    ✓✗✗✓ | 
    48  | 
    }  | 
    
1324  | 
    24  | 
    *p = '\0';  | 
    |
1325  | 
    lungetc(c);  | 
    ||
1326  | 
    24  | 
    break;  | 
    |
1327  | 
    ✓✗ | 24  | 
    }  | 
    
1328  | 
    24  | 
    val = symget(buf);  | 
    |
1329  | 
    24  | 
    		if (val == NULL) { | 
    |
1330  | 
    			yyerror("macro '%s' not defined", buf); | 
    ||
1331  | 
    24  | 
    return (findeol());  | 
    |
1332  | 
    }  | 
    ||
1333  | 
    parsebuf = val;  | 
    ||
1334  | 
    parseindex = 0;  | 
    ||
1335  | 
    goto top;  | 
    ||
1336  | 
    }  | 
    ||
1337  | 
    500  | 
    ||
1338  | 
    500  | 
    	switch (c) { | 
    |
1339  | 
    case '\'':  | 
    ||
1340  | 
    500  | 
    case '"':  | 
    |
1341  | 
    500  | 
    quotec = c;  | 
    |
1342  | 
    ✓✓ | 1088  | 
    		while (1) { | 
    
1343  | 
    500  | 
    if ((c = lgetc(quotec)) == EOF)  | 
    |
1344  | 
    ✓✗✗✓ | 
    1000  | 
    return (0);  | 
    
1345  | 
    500  | 
    			if (c == '\n') { | 
    |
1346  | 
    file->lineno++;  | 
    ||
1347  | 
    500  | 
    continue;  | 
    |
1348  | 
    ✓✓ | 500  | 
    			} else if (c == '\\') { | 
    
1349  | 
    88  | 
    if ((next = lgetc(quotec)) == EOF)  | 
    |
1350  | 
    500  | 
    return (0);  | 
    |
1351  | 
    if (next == quotec || c == ' ' || c == '\t')  | 
    ||
1352  | 
    500  | 
    c = next;  | 
    |
1353  | 
    8  | 
    				else if (next == '\n') { | 
    |
1354  | 
    8  | 
    file->lineno++;  | 
    |
1355  | 
    8  | 
    continue;  | 
    |
1356  | 
    } else  | 
    ||
1357  | 
    8  | 
    lungetc(next);  | 
    |
1358  | 
    120  | 
    			} else if (c == quotec) { | 
    |
1359  | 
    120  | 
    *p = '\0';  | 
    |
1360  | 
    120  | 
    break;  | 
    |
1361  | 
    ✓✓ | 264  | 
    			} else if (c == '\0') { | 
    
1362  | 
    120  | 
    				yyerror("syntax error"); | 
    |
1363  | 
    ✓✗✗✓ | 
    240  | 
    return (findeol());  | 
    
1364  | 
    120  | 
    }  | 
    |
1365  | 
    			if (p + 1 >= buf + sizeof(buf) - 1) { | 
    ||
1366  | 
    120  | 
    				yyerror("string too long"); | 
    |
1367  | 
    ✓✓ | 120  | 
    return (findeol());  | 
    
1368  | 
    24  | 
    }  | 
    |
1369  | 
    120  | 
    *p++ = c;  | 
    |
1370  | 
    }  | 
    ||
1371  | 
    120  | 
    yylval.v.string = strdup(buf);  | 
    |
1372  | 
    16  | 
    if (yylval.v.string == NULL)  | 
    |
1373  | 
    16  | 
    err(1, "yylex: strdup");  | 
    |
1374  | 
    16  | 
    return (STRING);  | 
    |
1375  | 
    }  | 
    ||
1376  | 
    16  | 
    ||
1377  | 
    ✗✓ | 32  | 
    #define allowed_to_end_number(x) \  | 
    
1378  | 
    (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')  | 
    ||
1379  | 
    |||
1380  | 
    	if (c == '-' || isdigit(c)) { | 
    ||
1381  | 
    		do { | 
    ||
1382  | 
    *p++ = c;  | 
    ||
1383  | 
    			if ((unsigned)(p-buf) >= sizeof(buf)) { | 
    ||
1384  | 
    				yyerror("string too long"); | 
    ||
1385  | 
    return (findeol());  | 
    ||
1386  | 
    }  | 
    ||
1387  | 
    } while ((c = lgetc(0)) != EOF && isdigit(c));  | 
    ||
1388  | 
    lungetc(c);  | 
    ||
1389  | 
    32  | 
    if (p == buf + 1 && buf[0] == '-')  | 
    |
1390  | 
    32  | 
    goto nodigits;  | 
    |
1391  | 
    32  | 
    		if (c == EOF || allowed_to_end_number(c)) { | 
    |
1392  | 
    ✓✓ | 88  | 
    const char *errstr = NULL;  | 
    
1393  | 
    32  | 
    ||
1394  | 
    ✓✗✗✓ | 
    64  | 
    *p = '\0';  | 
    
1395  | 
    32  | 
    yylval.v.number = strtonum(buf, LLONG_MIN,  | 
    |
1396  | 
    LLONG_MAX, &errstr);  | 
    ||
1397  | 
    32  | 
    			if (errstr) { | 
    |
1398  | 
    ✓✓ | 32  | 
    				yyerror("\"%s\" invalid number: %s", | 
    
1399  | 
    24  | 
    buf, errstr);  | 
    |
1400  | 
    32  | 
    return (findeol());  | 
    |
1401  | 
    }  | 
    ||
1402  | 
    32  | 
    return (NUMBER);  | 
    |
1403  | 
    		} else { | 
    ||
1404  | 
    nodigits:  | 
    ||
1405  | 
    while (p > buf + 1)  | 
    ||
1406  | 
    lungetc(*--p);  | 
    ||
1407  | 
    c = *--p;  | 
    ||
1408  | 
    if (c == '-')  | 
    ||
1409  | 
    return (c);  | 
    ||
1410  | 
    }  | 
    ||
1411  | 
    }  | 
    ||
1412  | 
    |||
1413  | 
    #define allowed_in_string(x) \  | 
    ||
1414  | 
    	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ | 
    ||
1415  | 
    	x != '{' && x != '}' && x != '<' && x != '>' && \ | 
    ||
1416  | 
    x != '!' && x != '=' && x != '#' && \  | 
    ||
1417  | 
    ✗✓ | 32  | 
    x != ',' && x != '/'))  | 
    
1418  | 
    |||
1419  | 
    	if (isalnum(c) || c == ':' || c == '_') { | 
    ||
1420  | 
    		do { | 
    ||
1421  | 
    *p++ = c;  | 
    ||
1422  | 
    			if ((unsigned)(p-buf) >= sizeof(buf)) { | 
    ||
1423  | 
    				yyerror("string too long"); | 
    ||
1424  | 
    return (findeol());  | 
    ||
1425  | 
    }  | 
    ||
1426  | 
    } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));  | 
    ||
1427  | 
    lungetc(c);  | 
    ||
1428  | 
    32  | 
    *p = '\0';  | 
    |
1429  | 
    32  | 
    if ((token = lookup(buf)) == STRING)  | 
    |
1430  | 
    32  | 
    if ((yylval.v.string = strdup(buf)) == NULL)  | 
    |
1431  | 
    32  | 
    err(1, "yylex: strdup");  | 
    |
1432  | 
    ✗✓ | 64  | 
    return (token);  | 
    
1433  | 
    32  | 
    }  | 
    |
1434  | 
    ✓✗✗✓ | 
    64  | 
    	if (c == '\n') { | 
    
1435  | 
    32  | 
    yylval.lineno = file->lineno;  | 
    |
1436  | 
    file->lineno++;  | 
    ||
1437  | 
    32  | 
    }  | 
    |
1438  | 
    ✗✓ | 32  | 
    if (c == EOF)  | 
    
1439  | 
    return (0);  | 
    ||
1440  | 
    32  | 
    return (c);  | 
    |
1441  | 
    }  | 
    ||
1442  | 
    32  | 
    ||
1443  | 
    ✗✓ | 8  | 
    int  | 
    
1444  | 
    check_file_secrecy(int fd, const char *fname)  | 
    ||
1445  | 
    { | 
    ||
1446  | 
    struct stat st;  | 
    ||
1447  | 
    |||
1448  | 
    	if (fstat(fd, &st)) { | 
    ||
1449  | 
    		log_warn("cannot stat %s", fname); | 
    ||
1450  | 
    return (-1);  | 
    ||
1451  | 
    }  | 
    ||
1452  | 
    8  | 
    	if (st.st_uid != 0 && st.st_uid != getuid()) { | 
    |
1453  | 
    8  | 
    		log_warnx("%s: owner not root or current user", fname); | 
    |
1454  | 
    8  | 
    return (-1);  | 
    |
1455  | 
    }  | 
    ||
1456  | 
    8  | 
    	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) { | 
    |
1457  | 
    		log_warnx("%s: group writable or world read/writable", fname); | 
    ||
1458  | 
    return (-1);  | 
    ||
1459  | 
    }  | 
    ||
1460  | 
    return (0);  | 
    ||
1461  | 
    }  | 
    ||
1462  | 
    |||
1463  | 
    struct file *  | 
    ||
1464  | 
    pushfile(const char *name, int secret)  | 
    ||
1465  | 
    { | 
    ||
1466  | 
    struct file *nfile;  | 
    ||
1467  | 
    |||
1468  | 
    	if ((nfile = calloc(1, sizeof(struct file))) == NULL) { | 
    ||
1469  | 
    		log_warn("%s: malloc", __func__); | 
    ||
1470  | 
    return (NULL);  | 
    ||
1471  | 
    }  | 
    ||
1472  | 
    48  | 
    	if ((nfile->name = strdup(name)) == NULL) { | 
    |
1473  | 
    ✗✓ | 48  | 
    		log_warn("%s: malloc", __func__); | 
    
1474  | 
    free(nfile);  | 
    ||
1475  | 
    return (NULL);  | 
    ||
1476  | 
    }  | 
    ||
1477  | 
    	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { | 
    ||
1478  | 
    		log_warn("%s: %s", __func__, nfile->name); | 
    ||
1479  | 
    free(nfile->name);  | 
    ||
1480  | 
    ✗✓ | 48  | 
    free(nfile);  | 
    
1481  | 
    return (NULL);  | 
    ||
1482  | 
    } else if (secret &&  | 
    ||
1483  | 
    	    check_file_secrecy(fileno(nfile->stream), nfile->name)) { | 
    ||
1484  | 
    fclose(nfile->stream);  | 
    ||
1485  | 
    free(nfile->name);  | 
    ||
1486  | 
    free(nfile);  | 
    ||
1487  | 
    48  | 
    return (NULL);  | 
    |
1488  | 
    ✗✓ | 96  | 
    }  | 
    
1489  | 
    48  | 
    nfile->lineno = 1;  | 
    |
1490  | 
    TAILQ_INSERT_TAIL(&files, nfile, entry);  | 
    ||
1491  | 
    return (nfile);  | 
    ||
1492  | 
    }  | 
    ||
1493  | 
    |||
1494  | 
    int  | 
    ||
1495  | 
    popfile(void)  | 
    ||
1496  | 
    { | 
    ||
1497  | 
    48  | 
    struct file *prev;  | 
    |
1498  | 
    |||
1499  | 
    48  | 
    if ((prev = TAILQ_PREV(file, files, entry)) != NULL)  | 
    |
1500  | 
    prev->errors += file->errors;  | 
    ||
1501  | 
    |||
1502  | 
    TAILQ_REMOVE(&files, file, entry);  | 
    ||
1503  | 
    fclose(file->stream);  | 
    ||
1504  | 
    free(file->name);  | 
    ||
1505  | 
    free(file);  | 
    ||
1506  | 
    file = prev;  | 
    ||
1507  | 
    return (file ? 0 : EOF);  | 
    ||
1508  | 
    }  | 
    ||
1509  | 
    40  | 
    ||
1510  | 
    ✗✓ | 40  | 
    int  | 
    
1511  | 
    parse_config(const char *filename, struct relayd *x_conf)  | 
    ||
1512  | 
    { | 
    ||
1513  | 
    struct sym *sym, *next;  | 
    ||
1514  | 
    |||
1515  | 
    conf = x_conf;  | 
    ||
1516  | 
    	if (config_init(conf) == -1) { | 
    ||
1517  | 
    ✗✓ | 40  | 
    		log_warn("%s: cannot initialize configuration", __func__); | 
    
1518  | 
    return (-1);  | 
    ||
1519  | 
    }  | 
    ||
1520  | 
    |||
1521  | 
    errors = 0;  | 
    ||
1522  | 
    |||
1523  | 
    if ((file = pushfile(filename, 0)) == NULL)  | 
    ||
1524  | 
    40  | 
    return (-1);  | 
    |
1525  | 
    ✗✓ | 80  | 
    |
1526  | 
    40  | 
    topfile = file;  | 
    |
1527  | 
    setservent(1);  | 
    ||
1528  | 
    |||
1529  | 
    yyparse();  | 
    ||
1530  | 
    errors = file->errors;  | 
    ||
1531  | 
    popfile();  | 
    ||
1532  | 
    |||
1533  | 
    endservent();  | 
    ||
1534  | 
    40  | 
    endprotoent();  | 
    |
1535  | 
    |||
1536  | 
    40  | 
    /* Free macros */  | 
    |
1537  | 
    24  | 
    	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) { | 
    |
1538  | 
    ✗✓ | 24  | 
    		if (!sym->persist) { | 
    
1539  | 
    free(sym->nam);  | 
    ||
1540  | 
    free(sym->val);  | 
    ||
1541  | 
    TAILQ_REMOVE(&symhead, sym, entry);  | 
    ||
1542  | 
    free(sym);  | 
    ||
1543  | 
    }  | 
    ||
1544  | 
    }  | 
    ||
1545  | 
    ✗✓ | 24  | 
    |
1546  | 
    return (errors ? -1 : 0);  | 
    ||
1547  | 
    }  | 
    ||
1548  | 
    |||
1549  | 
    int  | 
    ||
1550  | 
    load_config(const char *filename, struct relayd *x_conf)  | 
    ||
1551  | 
    { | 
    ||
1552  | 
    24  | 
    struct sym *sym, *next;  | 
    |
1553  | 
    ✗✓ | 48  | 
    struct table *nexttb;  | 
    
1554  | 
    24  | 
    struct host *h, *ph;  | 
    |
1555  | 
    struct relay_table *rlt;  | 
    ||
1556  | 
    |||
1557  | 
    conf = x_conf;  | 
    ||
1558  | 
    conf->sc_conf.flags = 0;  | 
    ||
1559  | 
    |||
1560  | 
    loadcfg = 1;  | 
    ||
1561  | 
    errors = 0;  | 
    ||
1562  | 
    24  | 
    last_host_id = last_table_id = last_rdr_id = last_proto_id =  | 
    |
1563  | 
    last_relay_id = last_rt_id = last_nr_id = 0;  | 
    ||
1564  | 
    24  | 
    ||
1565  | 
    rdr = NULL;  | 
    ||
1566  | 
    table = NULL;  | 
    ||
1567  | 
    rlay = NULL;  | 
    ||
1568  | 
    proto = NULL;  | 
    ||
1569  | 
    router = NULL;  | 
    ||
1570  | 
    |||
1571  | 
    if ((file = pushfile(filename, 0)) == NULL)  | 
    ||
1572  | 
    return (-1);  | 
    ||
1573  | 
    |||
1574  | 
    ✗✓ | 8  | 
    topfile = file;  | 
    
1575  | 
    setservent(1);  | 
    ||
1576  | 
    |||
1577  | 
    yyparse();  | 
    ||
1578  | 
    errors = file->errors;  | 
    ||
1579  | 
    popfile();  | 
    ||
1580  | 
    |||
1581  | 
    endservent();  | 
    ||
1582  | 
    ✓✗ | 8  | 
    endprotoent();  | 
    
1583  | 
    ✗✓ | 16  | 
    |
1584  | 
    16  | 
    /* Free macros and check which have not been used. */  | 
    |
1585  | 
    	for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { | 
    ||
1586  | 
    8  | 
    next = TAILQ_NEXT(sym, entry);  | 
    |
1587  | 
    8  | 
    if ((conf->sc_conf.opts & RELAYD_OPT_VERBOSE) && !sym->used)  | 
    |
1588  | 
    fprintf(stderr, "warning: macro '%s' not "  | 
    ||
1589  | 
    8  | 
    "used\n", sym->nam);  | 
    |
1590  | 
    		if (!sym->persist) { | 
    ||
1591  | 
    8  | 
    free(sym->nam);  | 
    |
1592  | 
    free(sym->val);  | 
    ||
1593  | 
    548  | 
    TAILQ_REMOVE(&symhead, sym, entry);  | 
    |
1594  | 
    716  | 
    free(sym);  | 
    |
1595  | 
    168  | 
    }  | 
    |
1596  | 
    }  | 
    ||
1597  | 
    96  | 
    ||
1598  | 
    136  | 
    if (TAILQ_EMPTY(conf->sc_rdrs) &&  | 
    |
1599  | 
    96  | 
    TAILQ_EMPTY(conf->sc_relays) &&  | 
    |
1600  | 
    64  | 
    	    TAILQ_EMPTY(conf->sc_rts)) { | 
    |
1601  | 
    16  | 
    		log_warnx("no actions, nothing to do"); | 
    |
1602  | 
    540  | 
    errors++;  | 
    |
1603  | 
    532  | 
    }  | 
    |
1604  | 
    |||
1605  | 
    /* Cleanup relay list to inherit */  | 
    ||
1606  | 
    	while ((rlay = TAILQ_FIRST(&relays)) != NULL) { | 
    ||
1607  | 
    TAILQ_REMOVE(&relays, rlay, rl_entry);  | 
    ||
1608  | 
    ✓✓ | 556  | 
    		while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) { | 
    
1609  | 
    8  | 
    TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);  | 
    |
1610  | 
    8  | 
    free(rlt);  | 
    |
1611  | 
    }  | 
    ||
1612  | 
    free(rlay);  | 
    ||
1613  | 
    ✗✓ | 1096  | 
    }  | 
    
1614  | 
    |||
1615  | 
    	if (timercmp(&conf->sc_conf.timeout, &conf->sc_conf.interval, >=)) { | 
    ||
1616  | 
    ✗✓ | 548  | 
    		log_warnx("global timeout exceeds interval"); | 
    
1617  | 
    errors++;  | 
    ||
1618  | 
    }  | 
    ||
1619  | 
    |||
1620  | 
    /* Verify that every table is used */  | 
    ||
1621  | 
    548  | 
    for (table = TAILQ_FIRST(conf->sc_tables); table != NULL;  | 
    |
1622  | 
    	     table = nexttb) { | 
    ||
1623  | 
    ✗✓ | 548  | 
    nexttb = TAILQ_NEXT(table, entry);  | 
    
1624  | 
    		if (table->conf.port == 0) { | 
    ||
1625  | 
    TAILQ_REMOVE(conf->sc_tables, table, entry);  | 
    ||
1626  | 
    ✗✓ | 1096  | 
    			while ((h = TAILQ_FIRST(&table->hosts)) != NULL) { | 
    
1627  | 
    548  | 
    TAILQ_REMOVE(&table->hosts, h, entry);  | 
    |
1628  | 
    free(h);  | 
    ||
1629  | 
    }  | 
    ||
1630  | 
    if (table->sendbuf != NULL)  | 
    ||
1631  | 
    free(table->sendbuf);  | 
    ||
1632  | 
    free(table);  | 
    ||
1633  | 
    continue;  | 
    ||
1634  | 
    548  | 
    }  | 
    |
1635  | 
    ✗✓ | 548  | 
    |
1636  | 
    		TAILQ_FOREACH(h, &table->hosts, entry) { | 
    ||
1637  | 
    			if (h->conf.parentid) { | 
    ||
1638  | 
    ph = host_find(conf, h->conf.parentid);  | 
    ||
1639  | 
    |||
1640  | 
    548  | 
    /* Validate the parent id */  | 
    |
1641  | 
    548  | 
    if (h->conf.id == h->conf.parentid ||  | 
    |
1642  | 
    548  | 
    ph == NULL || ph->conf.parentid)  | 
    |
1643  | 
    548  | 
    ph = NULL;  | 
    |
1644  | 
    548  | 
    ||
1645  | 
    ✗✓ | 548  | 
    				if (ph == NULL) { | 
    
1646  | 
    					log_warnx("host parent id %d invalid", | 
    ||
1647  | 
    h->conf.parentid);  | 
    ||
1648  | 
    errors++;  | 
    ||
1649  | 
    } else  | 
    ||
1650  | 
    548  | 
    SLIST_INSERT_HEAD(&ph->children,  | 
    |
1651  | 
    548  | 
    h, child);  | 
    |
1652  | 
    ✗✓✓✓ | 
    548  | 
    }  | 
    
1653  | 
    }  | 
    ||
1654  | 
    |||
1655  | 
    ✗✓ | 548  | 
    		if (!(table->conf.flags & F_USED)) { | 
    
1656  | 
    			log_warnx("unused table: %s", table->conf.name); | 
    ||
1657  | 
    errors++;  | 
    ||
1658  | 
    }  | 
    ||
1659  | 
    if (timercmp(&table->conf.timeout,  | 
    ||
1660  | 
    ✗✓ | 548  | 
    		    &conf->sc_conf.interval, >=)) { | 
    
1661  | 
    			log_warnx("table timeout exceeds interval: %s", | 
    ||
1662  | 
    table->conf.name);  | 
    ||
1663  | 
    errors++;  | 
    ||
1664  | 
    }  | 
    ||
1665  | 
    }  | 
    ||
1666  | 
    ✓✗✗✓ | 
    556  | 
    |
1667  | 
    ✓✓ | 548  | 
    /* Verify that every non-default protocol is used */  | 
    
1668  | 
    8  | 
    	TAILQ_FOREACH(proto, conf->sc_protos, entry) { | 
    |
1669  | 
    		if (!(proto->flags & F_USED)) { | 
    ||
1670  | 
    			log_warnx("unused protocol: %s", proto->name); | 
    ||
1671  | 
    }  | 
    ||
1672  | 
    }  | 
    ||
1673  | 
    ✗✓ | 548  | 
    |
1674  | 
    return (errors ? -1 : 0);  | 
    ||
1675  | 
    }  | 
    ||
1676  | 
    |||
1677  | 
    ✗✓ | 548  | 
    int  | 
    
1678  | 
    symset(const char *nam, const char *val, int persist)  | 
    ||
1679  | 
    { | 
    ||
1680  | 
    struct sym *sym;  | 
    ||
1681  | 
    |||
1682  | 
    548  | 
    	TAILQ_FOREACH(sym, &symhead, entry) { | 
    |
1683  | 
    548  | 
    if (strcmp(nam, sym->nam) == 0)  | 
    |
1684  | 
    548  | 
    break;  | 
    |
1685  | 
    }  | 
    ||
1686  | 
    548  | 
    ||
1687  | 
    	if (sym != NULL) { | 
    ||
1688  | 
    ✗✓ | 1096  | 
    if (sym->persist == 1)  | 
    
1689  | 
    return (0);  | 
    ||
1690  | 
    		else { | 
    ||
1691  | 
    free(sym->nam);  | 
    ||
1692  | 
    free(sym->val);  | 
    ||
1693  | 
    TAILQ_REMOVE(&symhead, sym, entry);  | 
    ||
1694  | 
    548  | 
    free(sym);  | 
    |
1695  | 
    ✗✓ | 548  | 
    }  | 
    
1696  | 
    }  | 
    ||
1697  | 
    if ((sym = calloc(1, sizeof(*sym))) == NULL)  | 
    ||
1698  | 
    return (-1);  | 
    ||
1699  | 
    |||
1700  | 
    sym->nam = strdup(nam);  | 
    ||
1701  | 
    	if (sym->nam == NULL) { | 
    ||
1702  | 
    free(sym);  | 
    ||
1703  | 
    548  | 
    return (-1);  | 
    |
1704  | 
    }  | 
    ||
1705  | 
    sym->val = strdup(val);  | 
    ||
1706  | 
    	if (sym->val == NULL) { | 
    ||
1707  | 
    ✗✓ | 548  | 
    free(sym->nam);  | 
    
1708  | 
    free(sym);  | 
    ||
1709  | 
    return (-1);  | 
    ||
1710  | 
    }  | 
    ||
1711  | 
    sym->used = 0;  | 
    ||
1712  | 
    sym->persist = persist;  | 
    ||
1713  | 
    ✗✓ | 548  | 
    TAILQ_INSERT_TAIL(&symhead, sym, entry);  | 
    
1714  | 
    return (0);  | 
    ||
1715  | 
    }  | 
    ||
1716  | 
    |||
1717  | 
    int  | 
    ||
1718  | 
    cmdline_symset(char *s)  | 
    ||
1719  | 
    548  | 
    { | 
    |
1720  | 
    ✗✓ | 548  | 
    char *sym, *val;  | 
    
1721  | 
    int ret;  | 
    ||
1722  | 
    size_t len;  | 
    ||
1723  | 
    |||
1724  | 
    if ((val = strrchr(s, '=')) == NULL)  | 
    ||
1725  | 
    548  | 
    return (-1);  | 
    |
1726  | 
    548  | 
    ||
1727  | 
    548  | 
    len = strlen(s) - strlen(val) + 1;  | 
    |
1728  | 
    548  | 
    if ((sym = malloc(len)) == NULL)  | 
    |
1729  | 
    ✓✓ | 548  | 
    errx(1, "cmdline_symset: malloc");  | 
    
1730  | 
    132  | 
    ||
1731  | 
    132  | 
    (void)strlcpy(sym, s, len);  | 
    |
1732  | 
    132  | 
    ||
1733  | 
    548  | 
    ret = symset(sym, val + 1, 1);  | 
    |
1734  | 
    548  | 
    free(sym);  | 
    |
1735  | 
    ✗✓ | 1096  | 
    |
1736  | 
    return (ret);  | 
    ||
1737  | 
    548  | 
    }  | 
    |
1738  | 
    ✗✓ | 548  | 
    |
1739  | 
    char *  | 
    ||
1740  | 
    symget(const char *nam)  | 
    ||
1741  | 
    { | 
    ||
1742  | 
    ✓✓ | 548  | 
    struct sym *sym;  | 
    
1743  | 
    132  | 
    ||
1744  | 
    132  | 
    	TAILQ_FOREACH(sym, &symhead, entry) { | 
    |
1745  | 
    132  | 
    		if (strcmp(nam, sym->nam) == 0) { | 
    |
1746  | 
    sym->used = 1;  | 
    ||
1747  | 
    return (sym->val);  | 
    ||
1748  | 
    ✗✓ | 32  | 
    }  | 
    
1749  | 
    }  | 
    ||
1750  | 
    return (NULL);  | 
    ||
1751  | 
    }  | 
    ||
1752  | 
    ✗✓ | 32  | 
    |
1753  | 
    struct address *  | 
    ||
1754  | 
    host_v4(const char *s)  | 
    ||
1755  | 
    { | 
    ||
1756  | 
    struct in_addr ina;  | 
    ||
1757  | 
    struct sockaddr_in *sain;  | 
    ||
1758  | 
    struct address *h;  | 
    ||
1759  | 
    |||
1760  | 
    ✓✗ | 1096  | 
    bzero(&ina, sizeof(ina));  | 
    
1761  | 
    ✗✓ | 548  | 
    if (inet_pton(AF_INET, s, &ina) != 1)  | 
    
1762  | 
    return (NULL);  | 
    ||
1763  | 
    ✗✓ | 548  | 
    |
1764  | 
    if ((h = calloc(1, sizeof(*h))) == NULL)  | 
    ||
1765  | 
    fatal(__func__);  | 
    ||
1766  | 
    sain = (struct sockaddr_in *)&h->ss;  | 
    ||
1767  | 
    sain->sin_len = sizeof(struct sockaddr_in);  | 
    ||
1768  | 
    548  | 
    sain->sin_family = AF_INET;  | 
    |
1769  | 
    548  | 
    sain->sin_addr.s_addr = ina.s_addr;  | 
    |
1770  | 
    548  | 
    ||
1771  | 
    548  | 
    return (h);  | 
    |
1772  | 
    ✗✓ | 548  | 
    }  | 
    
1773  | 
    |||
1774  | 
    struct address *  | 
    ||
1775  | 
    host_v6(const char *s)  | 
    ||
1776  | 
    { | 
    ||
1777  | 
    struct addrinfo hints, *res;  | 
    ||
1778  | 
    540  | 
    struct sockaddr_in6 *sa_in6;  | 
    |
1779  | 
    struct address *h = NULL;  | 
    ||
1780  | 
    |||
1781  | 
    ✗✓ | 540  | 
    bzero(&hints, sizeof(hints));  | 
    
1782  | 
    hints.ai_family = AF_INET6;  | 
    ||
1783  | 
    hints.ai_socktype = SOCK_DGRAM; /* dummy */  | 
    ||
1784  | 
    hints.ai_flags = AI_NUMERICHOST;  | 
    ||
1785  | 
    	if (getaddrinfo(s, "0", &hints, &res) == 0) { | 
    ||
1786  | 
    if ((h = calloc(1, sizeof(*h))) == NULL)  | 
    ||
1787  | 
    ✗✓ | 540  | 
    fatal(__func__);  | 
    
1788  | 
    sa_in6 = (struct sockaddr_in6 *)&h->ss;  | 
    ||
1789  | 
    sa_in6->sin6_len = sizeof(struct sockaddr_in6);  | 
    ||
1790  | 
    sa_in6->sin6_family = AF_INET6;  | 
    ||
1791  | 
    memcpy(&sa_in6->sin6_addr,  | 
    ||
1792  | 
    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,  | 
    ||
1793  | 
    540  | 
    sizeof(sa_in6->sin6_addr));  | 
    |
1794  | 
    ✗✓ | 540  | 
    sa_in6->sin6_scope_id =  | 
    
1795  | 
    ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;  | 
    ||
1796  | 
    |||
1797  | 
    freeaddrinfo(res);  | 
    ||
1798  | 
    }  | 
    ||
1799  | 
    540  | 
    ||
1800  | 
    540  | 
    return (h);  | 
    |
1801  | 
    540  | 
    }  | 
    |
1802  | 
    |||
1803  | 
    540  | 
    int  | 
    |
1804  | 
    540  | 
    host_dns(const char *s, struct addresslist *al, int max,  | 
    |
1805  | 
    540  | 
    struct portrange *port, const char *ifname, int ipproto)  | 
    |
1806  | 
    ✗✓ | 1080  | 
    { | 
    
1807  | 
    struct addrinfo hints, *res0, *res;  | 
    ||
1808  | 
    int error, cnt = 0;  | 
    ||
1809  | 
    struct sockaddr_in *sain;  | 
    ||
1810  | 
    struct sockaddr_in6 *sin6;  | 
    ||
1811  | 
    struct address *h;  | 
    ||
1812  | 
    |||
1813  | 
    if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)  | 
    ||
1814  | 
    return (cnt);  | 
    ||
1815  | 
    |||
1816  | 
    bzero(&hints, sizeof(hints));  | 
    ||
1817  | 
    hints.ai_family = PF_UNSPEC;  | 
    ||
1818  | 
    hints.ai_socktype = SOCK_DGRAM; /* DUMMY */  | 
    ||
1819  | 
    hints.ai_flags = AI_ADDRCONFIG;  | 
    ||
1820  | 
    ✗✓ | 8  | 
    error = getaddrinfo(s, NULL, &hints, &res0);  | 
    
1821  | 
    if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)  | 
    ||
1822  | 
    return (0);  | 
    ||
1823  | 
    	if (error) { | 
    ||
1824  | 
    		log_warnx("%s: could not parse \"%s\": %s", __func__, s, | 
    ||
1825  | 
    8  | 
    gai_strerror(error));  | 
    |
1826  | 
    8  | 
    return (-1);  | 
    |
1827  | 
    8  | 
    }  | 
    |
1828  | 
    8  | 
    ||
1829  | 
    ✗✓ | 8  | 
    	for (res = res0; res && cnt < max; res = res->ai_next) { | 
    
1830  | 
    if (res->ai_family != AF_INET &&  | 
    ||
1831  | 
    res->ai_family != AF_INET6)  | 
    ||
1832  | 
    ✗✓✗✗ | 
    8  | 
    continue;  | 
    
1833  | 
    if ((h = calloc(1, sizeof(*h))) == NULL)  | 
    ||
1834  | 
    fatal(__func__);  | 
    ||
1835  | 
    |||
1836  | 
    if (port != NULL)  | 
    ||
1837  | 
    bcopy(port, &h->port, sizeof(h->port));  | 
    ||
1838  | 
    8  | 
    		if (ifname != NULL) { | 
    |
1839  | 
    8  | 
    if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=  | 
    |
1840  | 
    sizeof(h->ifname))  | 
    ||
1841  | 
    8  | 
    				log_warnx("%s: interface name truncated", | 
    |
1842  | 
    ✗✓ | 8  | 
    __func__);  | 
    
1843  | 
    freeaddrinfo(res0);  | 
    ||
1844  | 
    free(h);  | 
    ||
1845  | 
    return (-1);  | 
    ||
1846  | 
    }  | 
    ||
1847  | 
    if (ipproto != -1)  | 
    ||
1848  | 
    h->ipproto = ipproto;  | 
    ||
1849  | 
    h->ss.ss_family = res->ai_family;  | 
    ||
1850  | 
    |||
1851  | 
    		if (res->ai_family == AF_INET) { | 
    ||
1852  | 
    sain = (struct sockaddr_in *)&h->ss;  | 
    ||
1853  | 
    sain->sin_len = sizeof(struct sockaddr_in);  | 
    ||
1854  | 
    sain->sin_addr.s_addr = ((struct sockaddr_in *)  | 
    ||
1855  | 
    res->ai_addr)->sin_addr.s_addr;  | 
    ||
1856  | 
    		} else { | 
    ||
1857  | 
    sin6 = (struct sockaddr_in6 *)&h->ss;  | 
    ||
1858  | 
    sin6->sin6_len = sizeof(struct sockaddr_in6);  | 
    ||
1859  | 
    memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)  | 
    ||
1860  | 
    res->ai_addr)->sin6_addr, sizeof(struct in6_addr));  | 
    ||
1861  | 
    }  | 
    ||
1862  | 
    |||
1863  | 
    TAILQ_INSERT_HEAD(al, h, entry);  | 
    ||
1864  | 
    cnt++;  | 
    ||
1865  | 
    }  | 
    ||
1866  | 
    	if (cnt == max && res) { | 
    ||
1867  | 
    		log_warnx("%s: %s resolves to more than %d hosts", __func__, | 
    ||
1868  | 
    s, max);  | 
    ||
1869  | 
    }  | 
    ||
1870  | 
    freeaddrinfo(res0);  | 
    ||
1871  | 
    return (cnt);  | 
    ||
1872  | 
    }  | 
    ||
1873  | 
    |||
1874  | 
    int  | 
    ||
1875  | 
    host_if(const char *s, struct addresslist *al, int max,  | 
    ||
1876  | 
    struct portrange *port, const char *ifname, int ipproto)  | 
    ||
1877  | 
    { | 
    ||
1878  | 
    struct ifaddrs *ifap, *p;  | 
    ||
1879  | 
    struct sockaddr_in *sain;  | 
    ||
1880  | 
    struct sockaddr_in6 *sin6;  | 
    ||
1881  | 
    struct address *h;  | 
    ||
1882  | 
    int cnt = 0, af;  | 
    ||
1883  | 
    |||
1884  | 
    if (getifaddrs(&ifap) == -1)  | 
    ||
1885  | 
    		fatal("getifaddrs"); | 
    ||
1886  | 
    |||
1887  | 
    /* First search for IPv4 addresses */  | 
    ||
1888  | 
    af = AF_INET;  | 
    ||
1889  | 
    |||
1890  | 
    nextaf:  | 
    ||
1891  | 
    	for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) { | 
    ||
1892  | 
    if (p->ifa_addr->sa_family != af ||  | 
    ||
1893  | 
    (strcmp(s, p->ifa_name) != 0 &&  | 
    ||
1894  | 
    !is_if_in_group(p->ifa_name, s)))  | 
    ||
1895  | 
    continue;  | 
    ||
1896  | 
    if ((h = calloc(1, sizeof(*h))) == NULL)  | 
    ||
1897  | 
    			fatal("calloc"); | 
    ||
1898  | 
    |||
1899  | 
    if (port != NULL)  | 
    ||
1900  | 
    bcopy(port, &h->port, sizeof(h->port));  | 
    ||
1901  | 
    		if (ifname != NULL) { | 
    ||
1902  | 
    if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=  | 
    ||
1903  | 
    sizeof(h->ifname))  | 
    ||
1904  | 
    				log_warnx("%s: interface name truncated", | 
    ||
1905  | 
    __func__);  | 
    ||
1906  | 
    freeifaddrs(ifap);  | 
    ||
1907  | 
    return (-1);  | 
    ||
1908  | 
    }  | 
    ||
1909  | 
    if (ipproto != -1)  | 
    ||
1910  | 
    h->ipproto = ipproto;  | 
    ||
1911  | 
    h->ss.ss_family = af;  | 
    ||
1912  | 
    |||
1913  | 
    		if (af == AF_INET) { | 
    ||
1914  | 
    sain = (struct sockaddr_in *)&h->ss;  | 
    ||
1915  | 
    sain->sin_len = sizeof(struct sockaddr_in);  | 
    ||
1916  | 
    sain->sin_addr.s_addr = ((struct sockaddr_in *)  | 
    ||
1917  | 
    p->ifa_addr)->sin_addr.s_addr;  | 
    ||
1918  | 
    		} else { | 
    ||
1919  | 
    sin6 = (struct sockaddr_in6 *)&h->ss;  | 
    ||
1920  | 
    sin6->sin6_len = sizeof(struct sockaddr_in6);  | 
    ||
1921  | 
    memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)  | 
    ||
1922  | 
    p->ifa_addr)->sin6_addr, sizeof(struct in6_addr));  | 
    ||
1923  | 
    sin6->sin6_scope_id = ((struct sockaddr_in6 *)  | 
    ||
1924  | 
    p->ifa_addr)->sin6_scope_id;  | 
    ||
1925  | 
    }  | 
    ||
1926  | 
    |||
1927  | 
    TAILQ_INSERT_HEAD(al, h, entry);  | 
    ||
1928  | 
    cnt++;  | 
    ||
1929  | 
    }  | 
    ||
1930  | 
    	if (af == AF_INET) { | 
    ||
1931  | 
    /* Next search for IPv6 addresses */  | 
    ||
1932  | 
    af = AF_INET6;  | 
    ||
1933  | 
    goto nextaf;  | 
    ||
1934  | 
    }  | 
    ||
1935  | 
    |||
1936  | 
    	if (cnt > max) { | 
    ||
1937  | 
    		log_warnx("%s: %s resolves to more than %d hosts", __func__, | 
    ||
1938  | 
    s, max);  | 
    ||
1939  | 
    }  | 
    ||
1940  | 
    freeifaddrs(ifap);  | 
    ||
1941  | 
    return (cnt);  | 
    ||
1942  | 
    }  | 
    ||
1943  | 
    |||
1944  | 
    int  | 
    ||
1945  | 
    host(const char *s, struct addresslist *al, int max,  | 
    ||
1946  | 
    struct portrange *port, const char *ifname, int ipproto)  | 
    ||
1947  | 
    { | 
    ||
1948  | 
    struct address *h;  | 
    ||
1949  | 
    |||
1950  | 
    h = host_v4(s);  | 
    ||
1951  | 
    |||
1952  | 
    /* IPv6 address? */  | 
    ||
1953  | 
    if (h == NULL)  | 
    ||
1954  | 
    h = host_v6(s);  | 
    ||
1955  | 
    |||
1956  | 
    	if (h != NULL) { | 
    ||
1957  | 
    if (port != NULL)  | 
    ||
1958  | 
    bcopy(port, &h->port, sizeof(h->port));  | 
    ||
1959  | 
    		if (ifname != NULL) { | 
    ||
1960  | 
    if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=  | 
    ||
1961  | 
    			    sizeof(h->ifname)) { | 
    ||
1962  | 
    				log_warnx("%s: interface name truncated", | 
    ||
1963  | 
    __func__);  | 
    ||
1964  | 
    free(h);  | 
    ||
1965  | 
    return (-1);  | 
    ||
1966  | 
    }  | 
    ||
1967  | 
    }  | 
    ||
1968  | 
    if (ipproto != -1)  | 
    ||
1969  | 
    h->ipproto = ipproto;  | 
    ||
1970  | 
    |||
1971  | 
    TAILQ_INSERT_HEAD(al, h, entry);  | 
    ||
1972  | 
    return (1);  | 
    ||
1973  | 
    }  | 
    ||
1974  | 
    |||
1975  | 
    return (host_dns(s, al, max, port, ifname, ipproto));  | 
    ||
1976  | 
    }  | 
    ||
1977  | 
    |||
1978  | 
    void  | 
    ||
1979  | 
    host_free(struct addresslist *al)  | 
    ||
1980  | 
    { | 
    ||
1981  | 
    struct address *h;  | 
    ||
1982  | 
    |||
1983  | 
    	while ((h = TAILQ_FIRST(al)) != NULL) { | 
    ||
1984  | 
    TAILQ_REMOVE(al, h, entry);  | 
    ||
1985  | 
    free(h);  | 
    ||
1986  | 
    }  | 
    ||
1987  | 
    }  | 
    ||
1988  | 
    |||
1989  | 
    struct table *  | 
    ||
1990  | 
    table_inherit(struct table *tb)  | 
    ||
1991  | 
    { | 
    ||
1992  | 
    char pname[TABLE_NAME_SIZE + 6];  | 
    ||
1993  | 
    struct host *h, *dsth;  | 
    ||
1994  | 
    548  | 
    struct table *dsttb, *oldtb;  | 
    |
1995  | 
    |||
1996  | 
    548  | 
    /* Get the table or table template */  | 
    |
1997  | 
    	if ((dsttb = table_findbyname(conf, tb->conf.name)) == NULL) { | 
    ||
1998  | 
    		yyerror("unknown table %s", tb->conf.name); | 
    ||
1999  | 
    goto fail;  | 
    ||
2000  | 
    }  | 
    ||
2001  | 
    if (dsttb->conf.port != 0)  | 
    ||
2002  | 
    		fatal("invalid table");	/* should not happen */ | 
    ||
2003  | 
    |||
2004  | 
    	if (tb->conf.port == 0) { | 
    ||
2005  | 
    		yyerror("invalid port"); | 
    ||
2006  | 
    goto fail;  | 
    ||
2007  | 
    }  | 
    ||
2008  | 
    |||
2009  | 
    /* Check if a matching table already exists */  | 
    ||
2010  | 
    if (snprintf(pname, sizeof(pname), "%s:%u",  | 
    ||
2011  | 
    	    tb->conf.name, ntohs(tb->conf.port)) >= (int)sizeof(pname)) { | 
    ||
2012  | 
    		yyerror("invalid table name"); | 
    ||
2013  | 
    goto fail;  | 
    ||
2014  | 
    }  | 
    ||
2015  | 
    if (strlcpy(tb->conf.name, pname, sizeof(tb->conf.name)) >=  | 
    ||
2016  | 
    	    sizeof(tb->conf.name)) { | 
    ||
2017  | 
    		yyerror("invalid table mame"); | 
    ||
2018  | 
    goto fail;  | 
    ||
2019  | 
    }  | 
    ||
2020  | 
    ✗✓ | 8  | 
    	if ((oldtb = table_findbyconf(conf, tb)) != NULL) { | 
    
2021  | 
    purge_table(conf, NULL, tb);  | 
    ||
2022  | 
    return (oldtb);  | 
    ||
2023  | 
    ✗✓ | 16  | 
    }  | 
    
2024  | 
    8  | 
    ||
2025  | 
    /* Create a new table */  | 
    ||
2026  | 
    tb->conf.id = ++last_table_id;  | 
    ||
2027  | 
    	if (last_table_id == INT_MAX) { | 
    ||
2028  | 
    		yyerror("too many tables defined"); | 
    ||
2029  | 
    8  | 
    goto fail;  | 
    |
2030  | 
    8  | 
    }  | 
    |
2031  | 
    8  | 
    tb->conf.flags |= dsttb->conf.flags;  | 
    |
2032  | 
    |||
2033  | 
    16  | 
    /* Inherit global table options */  | 
    |
2034  | 
    8  | 
    if (tb->conf.timeout.tv_sec == 0 && tb->conf.timeout.tv_usec == 0)  | 
    |
2035  | 
    bcopy(&dsttb->conf.timeout, &tb->conf.timeout,  | 
    ||
2036  | 
    8  | 
    sizeof(struct timeval));  | 
    |
2037  | 
    |||
2038  | 
    /* Copy the associated hosts */  | 
    ||
2039  | 
    TAILQ_INIT(&tb->hosts);  | 
    ||
2040  | 
    	TAILQ_FOREACH(dsth, &dsttb->hosts, entry) { | 
    ||
2041  | 
    if ((h = (struct host *)  | 
    ||
2042  | 
    calloc(1, sizeof (*h))) == NULL)  | 
    ||
2043  | 
    			fatal("out of memory"); | 
    ||
2044  | 
    bcopy(dsth, h, sizeof(*h));  | 
    ||
2045  | 
    h->conf.id = ++last_host_id;  | 
    ||
2046  | 
    		if (last_host_id == INT_MAX) { | 
    ||
2047  | 
    			yyerror("too many hosts defined"); | 
    ||
2048  | 
    free(h);  | 
    ||
2049  | 
    goto fail;  | 
    ||
2050  | 
    }  | 
    ||
2051  | 
    h->conf.tableid = tb->conf.id;  | 
    ||
2052  | 
    h->tablename = tb->conf.name;  | 
    ||
2053  | 
    SLIST_INIT(&h->children);  | 
    ||
2054  | 
    TAILQ_INSERT_TAIL(&tb->hosts, h, entry);  | 
    ||
2055  | 
    TAILQ_INSERT_TAIL(&conf->sc_hosts, h, globalentry);  | 
    ||
2056  | 
    }  | 
    ||
2057  | 
    |||
2058  | 
    conf->sc_tablecount++;  | 
    ||
2059  | 
    TAILQ_INSERT_TAIL(conf->sc_tables, tb, entry);  | 
    ||
2060  | 
    |||
2061  | 
    return (tb);  | 
    ||
2062  | 
    |||
2063  | 
    fail:  | 
    ||
2064  | 
    purge_table(conf, NULL, tb);  | 
    ||
2065  | 
    return (NULL);  | 
    ||
2066  | 
    }  | 
    ||
2067  | 
    |||
2068  | 
    int  | 
    ||
2069  | 
    relay_id(struct relay *rl)  | 
    ||
2070  | 
    { | 
    ||
2071  | 
    rl->rl_conf.id = ++last_relay_id;  | 
    ||
2072  | 
    rl->rl_conf.tls_keyid = ++last_key_id;  | 
    ||
2073  | 
    rl->rl_conf.tls_cakeyid = ++last_key_id;  | 
    ||
2074  | 
    |||
2075  | 
    if (last_relay_id == INT_MAX || last_key_id == INT_MAX)  | 
    ||
2076  | 
    return (-1);  | 
    ||
2077  | 
    |||
2078  | 
    return (0);  | 
    ||
2079  | 
    }  | 
    ||
2080  | 
    |||
2081  | 
    struct relay *  | 
    ||
2082  | 
    relay_inherit(struct relay *ra, struct relay *rb)  | 
    ||
2083  | 
    { | 
    ||
2084  | 
    struct relay_config rc;  | 
    ||
2085  | 
    struct relay_table *rta, *rtb;  | 
    ||
2086  | 
    |||
2087  | 
    bcopy(&rb->rl_conf, &rc, sizeof(rc));  | 
    ||
2088  | 
    bcopy(ra, rb, sizeof(*rb));  | 
    ||
2089  | 
    |||
2090  | 
    bcopy(&rc.ss, &rb->rl_conf.ss, sizeof(rb->rl_conf.ss));  | 
    ||
2091  | 
    rb->rl_conf.port = rc.port;  | 
    ||
2092  | 
    rb->rl_conf.flags =  | 
    ||
2093  | 
    (ra->rl_conf.flags & ~F_TLS) | (rc.flags & F_TLS);  | 
    ||
2094  | 
    8  | 
    	if (!(rb->rl_conf.flags & F_TLS)) { | 
    |
2095  | 
    rb->rl_tls_cert = NULL;  | 
    ||
2096  | 
    ✗✓ | 16  | 
    rb->rl_conf.tls_cert_len = 0;  | 
    
2097  | 
    8  | 
    rb->rl_tls_key = NULL;  | 
    |
2098  | 
    rb->rl_conf.tls_key_len = 0;  | 
    ||
2099  | 
    }  | 
    ||
2100  | 
    TAILQ_INIT(&rb->rl_tables);  | 
    ||
2101  | 
    |||
2102  | 
    	if (relay_id(rb) == -1) { | 
    ||
2103  | 
    8  | 
    		yyerror("too many relays defined"); | 
    |
2104  | 
    ✗✓ | 8  | 
    goto err;  | 
    
2105  | 
    }  | 
    ||
2106  | 
    |||
2107  | 
    if (snprintf(rb->rl_conf.name, sizeof(rb->rl_conf.name), "%s%u:%u",  | 
    ||
2108  | 
    ra->rl_conf.name, rb->rl_conf.id, ntohs(rc.port)) >=  | 
    ||
2109  | 
    8  | 
    	    (int)sizeof(rb->rl_conf.name)) { | 
    |
2110  | 
    8  | 
    		yyerror("invalid relay name"); | 
    |
2111  | 
    8  | 
    goto err;  | 
    |
2112  | 
    8  | 
    }  | 
    |
2113  | 
    ✗✓ | 16  | 
    |
2114  | 
    if (relay_findbyname(conf, rb->rl_conf.name) != NULL ||  | 
    ||
2115  | 
    	    relay_findbyaddr(conf, &rb->rl_conf) != NULL) { | 
    ||
2116  | 
    540  | 
    		yyerror("relay %s defined twice", rb->rl_conf.name); | 
    |
2117  | 
    540  | 
    goto err;  | 
    |
2118  | 
    }  | 
    ||
2119  | 
    	if (relay_load_certfiles(rb) == -1) { | 
    ||
2120  | 
    		yyerror("cannot load certificates for relay %s", | 
    ||
2121  | 
    rb->rl_conf.name);  | 
    ||
2122  | 
    goto err;  | 
    ||
2123  | 
    }  | 
    ||
2124  | 
    |||
2125  | 
    	TAILQ_FOREACH(rta, &ra->rl_tables, rlt_entry) { | 
    ||
2126  | 
    		if ((rtb = calloc(1, sizeof(*rtb))) == NULL) { | 
    ||
2127  | 
    			yyerror("cannot allocate relay table"); | 
    ||
2128  | 
    goto err;  | 
    ||
2129  | 
    }  | 
    ||
2130  | 
    rtb->rlt_table = rta->rlt_table;  | 
    ||
2131  | 
    rtb->rlt_mode = rta->rlt_mode;  | 
    ||
2132  | 
    rtb->rlt_flags = rta->rlt_flags;  | 
    ||
2133  | 
    |||
2134  | 
    TAILQ_INSERT_TAIL(&rb->rl_tables, rtb, rlt_entry);  | 
    ||
2135  | 
    }  | 
    ||
2136  | 
    |||
2137  | 
    conf->sc_relaycount++;  | 
    ||
2138  | 
    SPLAY_INIT(&rlay->rl_sessions);  | 
    ||
2139  | 
    TAILQ_INSERT_TAIL(conf->sc_relays, rb, rl_entry);  | 
    ||
2140  | 
    |||
2141  | 
    return (rb);  | 
    ||
2142  | 
    |||
2143  | 
    err:  | 
    ||
2144  | 
    	while ((rtb = TAILQ_FIRST(&rb->rl_tables))) { | 
    ||
2145  | 
    TAILQ_REMOVE(&rb->rl_tables, rtb, rlt_entry);  | 
    ||
2146  | 
    free(rtb);  | 
    ||
2147  | 
    }  | 
    ||
2148  | 
    free(rb);  | 
    ||
2149  | 
    return (NULL);  | 
    ||
2150  | 
    }  | 
    ||
2151  | 
    |||
2152  | 
    int  | 
    ||
2153  | 
    getservice(char *n)  | 
    ||
2154  | 
    { | 
    ||
2155  | 
    struct servent *s;  | 
    ||
2156  | 
    const char *errstr;  | 
    ||
2157  | 
    long long llval;  | 
    ||
2158  | 
    |||
2159  | 
    llval = strtonum(n, 0, UINT16_MAX, &errstr);  | 
    ||
2160  | 
    	if (errstr) { | 
    ||
2161  | 
    s = getservbyname(n, "tcp");  | 
    ||
2162  | 
    if (s == NULL)  | 
    ||
2163  | 
    s = getservbyname(n, "udp");  | 
    ||
2164  | 
    		if (s == NULL) { | 
    ||
2165  | 
    			yyerror("unknown port %s", n); | 
    ||
2166  | 
    return (-1);  | 
    ||
2167  | 
    }  | 
    ||
2168  | 
    return (s->s_port);  | 
    ||
2169  | 
    }  | 
    ||
2170  | 
    |||
2171  | 
    return (htons((u_short)llval));  | 
    ||
2172  | 
    }  | 
    ||
2173  | 
    |||
2174  | 
    int  | 
    ||
2175  | 
    is_if_in_group(const char *ifname, const char *groupname)  | 
    ||
2176  | 
    { | 
    ||
2177  | 
    unsigned int len;  | 
    ||
2178  | 
    struct ifgroupreq ifgr;  | 
    ||
2179  | 
    struct ifg_req *ifg;  | 
    ||
2180  | 
    int s;  | 
    ||
2181  | 
    int ret = 0;  | 
    ||
2182  | 
    |||
2183  | 
    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  | 
    ||
2184  | 
    err(1, "socket");  | 
    ||
2185  | 
    |||
2186  | 
    memset(&ifgr, 0, sizeof(ifgr));  | 
    ||
2187  | 
    if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ)  | 
    ||
2188  | 
    err(1, "IFNAMSIZ");  | 
    ||
2189  | 
    	if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { | 
    ||
2190  | 
    if (errno == EINVAL || errno == ENOTTY)  | 
    ||
2191  | 
    goto end;  | 
    ||
2192  | 
    err(1, "SIOCGIFGROUP");  | 
    ||
2193  | 
    }  | 
    ||
2194  | 
    |||
2195  | 
    len = ifgr.ifgr_len;  | 
    ||
2196  | 
    ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req),  | 
    ||
2197  | 
    sizeof(struct ifg_req));  | 
    ||
2198  | 
    if (ifgr.ifgr_groups == NULL)  | 
    ||
2199  | 
    err(1, "getifgroups");  | 
    ||
2200  | 
    if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)  | 
    ||
2201  | 
    err(1, "SIOCGIFGROUP");  | 
    ||
2202  | 
    |||
2203  | 
    ifg = ifgr.ifgr_groups;  | 
    ||
2204  | 
    	for (; ifg && len >= sizeof(struct ifg_req); ifg++) { | 
    ||
2205  | 
    len -= sizeof(struct ifg_req);  | 
    ||
2206  | 
    		if (strcmp(ifg->ifgrq_group, groupname) == 0) { | 
    ||
2207  | 
    ret = 1;  | 
    ||
2208  | 
    break;  | 
    ||
2209  | 
    }  | 
    ||
2210  | 
    }  | 
    ||
2211  | 
    free(ifgr.ifgr_groups);  | 
    ||
2212  | 
    |||
2213  | 
    end:  | 
    ||
2214  | 
    close(s);  | 
    ||
2215  | 
    return (ret);  | 
    ||
2216  | 
    }  | 
    ||
2217  | 
    #line 2210 "parse.c"  | 
    ||
2218  | 
    ✓✗ | 2208  | 
    /* allocate initial stack or double stack size, up to YYMAXDEPTH */  | 
    
2219  | 
    1104  | 
    static int yygrowstack(void)  | 
    |
2220  | 
    { | 
    ||
2221  | 
    unsigned int newsize;  | 
    ||
2222  | 
    long sslen;  | 
    ||
2223  | 
    short *newss;  | 
    ||
2224  | 
    1104  | 
    YYSTYPE *newvs;  | 
    |
2225  | 
    |||
2226  | 
    if ((newsize = yystacksize) == 0)  | 
    ||
2227  | 
    newsize = YYINITSTACKSIZE;  | 
    ||
2228  | 
    else if (newsize >= YYMAXDEPTH)  | 
    ||
2229  | 
    return -1;  | 
    ||
2230  | 
    ✓✗✓✗ | 
    2208  | 
    else if ((newsize *= 2) > YYMAXDEPTH)  | 
    
2231  | 
    newsize = YYMAXDEPTH;  | 
    ||
2232  | 
    ✗✓ | 2208  | 
    sslen = yyssp - yyss;  | 
    
2233  | 
    1104  | 
    #ifdef SIZE_MAX  | 
    |
2234  | 
    ✓✗ | 1104  | 
    #define YY_SIZE_MAX SIZE_MAX  | 
    
2235  | 
    #else  | 
    ||
2236  | 
    1104  | 
    #define YY_SIZE_MAX 0xffffffffU  | 
    |
2237  | 
    1104  | 
    #endif  | 
    |
2238  | 
    ✓✗✓✗ | 
    2208  | 
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)  | 
    
2239  | 
    goto bail;  | 
    ||
2240  | 
    ✗✓ | 2208  | 
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :  | 
    
2241  | 
    1104  | 
    (short *)malloc(newsize * sizeof *newss); /* overflow check above */  | 
    |
2242  | 
    ✓✗ | 1104  | 
    if (newss == NULL)  | 
    
2243  | 
    goto bail;  | 
    ||
2244  | 
    1104  | 
    yyss = newss;  | 
    |
2245  | 
    1104  | 
    yyssp = newss + sslen;  | 
    |
2246  | 
    1104  | 
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)  | 
    |
2247  | 
    1104  | 
    goto bail;  | 
    |
2248  | 
    1104  | 
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :  | 
    |
2249  | 
    (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */  | 
    ||
2250  | 
    if (newvs == NULL)  | 
    ||
2251  | 
    goto bail;  | 
    ||
2252  | 
    yyvs = newvs;  | 
    ||
2253  | 
    yyvsp = newvs + sslen;  | 
    ||
2254  | 
    yystacksize = newsize;  | 
    ||
2255  | 
    yysslim = yyss + newsize - 1;  | 
    ||
2256  | 
    return 0;  | 
    ||
2257  | 
    bail:  | 
    ||
2258  | 
    1104  | 
    if (yyss)  | 
    |
2259  | 
    free(yyss);  | 
    ||
2260  | 
    if (yyvs)  | 
    ||
2261  | 
    free(yyvs);  | 
    ||
2262  | 
    yyss = yyssp = NULL;  | 
    ||
2263  | 
    yyvs = yyvsp = NULL;  | 
    ||
2264  | 
    yystacksize = 0;  | 
    ||
2265  | 
    return -1;  | 
    ||
2266  | 
    }  | 
    ||
2267  | 
    |||
2268  | 
    #define YYABORT goto yyabort  | 
    ||
2269  | 
    #define YYREJECT goto yyabort  | 
    ||
2270  | 
    #define YYACCEPT goto yyaccept  | 
    ||
2271  | 
    #define YYERROR goto yyerrlab  | 
    ||
2272  | 
    int  | 
    ||
2273  | 
    yyparse(void)  | 
    ||
2274  | 
    { | 
    ||
2275  | 
    int yym, yyn, yystate;  | 
    ||
2276  | 
    #if YYDEBUG  | 
    ||
2277  | 
    const char *yys;  | 
    ||
2278  | 
    |||
2279  | 
    2208  | 
        if ((yys = getenv("YYDEBUG"))) | 
    |
2280  | 
    1104  | 
        { | 
    |
2281  | 
    1104  | 
    yyn = *yys;  | 
    |
2282  | 
    if (yyn >= '0' && yyn <= '9')  | 
    ||
2283  | 
    ✓✗✓✗ | 
    2208  | 
    yydebug = yyn - '0';  | 
    
2284  | 
    1104  | 
    }  | 
    |
2285  | 
    1104  | 
    #endif /* YYDEBUG */  | 
    |
2286  | 
    1104  | 
    ||
2287  | 
    yynerrs = 0;  | 
    ||
2288  | 
    yyerrflag = 0;  | 
    ||
2289  | 
    ✓✓ | 74408  | 
    yychar = (-1);  | 
    
2290  | 
    ✓✓ | 42084  | 
    |
2291  | 
    if (yyss == NULL && yygrowstack()) goto yyoverflow;  | 
    ||
2292  | 
    27684  | 
    yyssp = yyss;  | 
    |
2293  | 
    yyvsp = yyvs;  | 
    ||
2294  | 
    *yyssp = yystate = 0;  | 
    ||
2295  | 
    |||
2296  | 
    yyloop:  | 
    ||
2297  | 
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;  | 
    ||
2298  | 
    if (yychar < 0)  | 
    ||
2299  | 
        { | 
    ||
2300  | 
    if ((yychar = yylex()) < 0) yychar = 0;  | 
    ||
2301  | 
    #if YYDEBUG  | 
    ||
2302  | 
    if (yydebug)  | 
    ||
2303  | 
    27684  | 
            { | 
    |
2304  | 
    ✓✗✓✓ ✓✓  | 
    167196  | 
    yys = 0;  | 
    
2305  | 
    83028  | 
    if (yychar <= YYMAXTOKEN) yys = yyname[yychar];  | 
    |
2306  | 
    if (!yys) yys = "illegal-symbol";  | 
    ||
2307  | 
                printf("%sdebug: state %d, reading %d (%s)\n", | 
    ||
2308  | 
    YYPREFIX, yystate, yychar, yys);  | 
    ||
2309  | 
    }  | 
    ||
2310  | 
    #endif  | 
    ||
2311  | 
    }  | 
    ||
2312  | 
    ✗✓✗✗ | 
    31532  | 
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&  | 
    
2313  | 
    yyn <= YYTABLESIZE && yycheck[yyn] == yychar)  | 
    ||
2314  | 
        { | 
    ||
2315  | 
    #if YYDEBUG  | 
    ||
2316  | 
    31532  | 
    if (yydebug)  | 
    |
2317  | 
    31532  | 
                printf("%sdebug: state %d, shifting to state %d\n", | 
    |
2318  | 
    31532  | 
    YYPREFIX, yystate, yytable[yyn]);  | 
    |
2319  | 
    ✓✓ | 31580  | 
    #endif  | 
    
2320  | 
    31532  | 
    if (yyssp >= yysslim && yygrowstack())  | 
    |
2321  | 
            { | 
    ||
2322  | 
    ✓✓✓✗ ✓✓  | 
    42052  | 
    goto yyoverflow;  | 
    
2323  | 
    21000  | 
    }  | 
    |
2324  | 
    *++yyssp = yystate = yytable[yyn];  | 
    ||
2325  | 
    10492  | 
    *++yyvsp = yylval;  | 
    |
2326  | 
    10492  | 
    yychar = (-1);  | 
    |
2327  | 
    if (yyerrflag > 0) --yyerrflag;  | 
    ||
2328  | 
    ✗✓ | 60  | 
    goto yyloop;  | 
    
2329  | 
    }  | 
    ||
2330  | 
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&  | 
    ||
2331  | 
    yyn <= YYTABLESIZE && yycheck[yyn] == yychar)  | 
    ||
2332  | 
        { | 
    ||
2333  | 
    yyn = yytable[yyn];  | 
    ||
2334  | 
    goto yyreduce;  | 
    ||
2335  | 
    }  | 
    ||
2336  | 
    if (yyerrflag) goto yyinrecovery;  | 
    ||
2337  | 
    #if defined(__GNUC__)  | 
    ||
2338  | 
    8  | 
    goto yynewerror;  | 
    |
2339  | 
    #endif  | 
    ||
2340  | 
    ✓✓ | 68  | 
    yynewerror:  | 
    
2341  | 
        yyerror("syntax error"); | 
    ||
2342  | 
    24  | 
    #if defined(__GNUC__)  | 
    |
2343  | 
    40  | 
    goto yyerrlab;  | 
    |
2344  | 
    #endif  | 
    ||
2345  | 
    ✓✗✓✗ ✓✓  | 
    160  | 
    yyerrlab:  | 
    
2346  | 
    80  | 
    ++yynerrs;  | 
    |
2347  | 
    yyinrecovery:  | 
    ||
2348  | 
    if (yyerrflag < 3)  | 
    ||
2349  | 
        { | 
    ||
2350  | 
    yyerrflag = 3;  | 
    ||
2351  | 
    for (;;)  | 
    ||
2352  | 
            { | 
    ||
2353  | 
    ✗✓✗✗ | 
    24  | 
    if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&  | 
    
2354  | 
    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)  | 
    ||
2355  | 
                { | 
    ||
2356  | 
    #if YYDEBUG  | 
    ||
2357  | 
    24  | 
    if (yydebug)  | 
    |
2358  | 
    24  | 
                        printf("%sdebug: state %d, error recovery shifting\ | 
    |
2359  | 
    24  | 
    to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);  | 
    |
2360  | 
    #endif  | 
    ||
2361  | 
    if (yyssp >= yysslim && yygrowstack())  | 
    ||
2362  | 
                    { | 
    ||
2363  | 
    goto yyoverflow;  | 
    ||
2364  | 
    }  | 
    ||
2365  | 
    *++yyssp = yystate = yytable[yyn];  | 
    ||
2366  | 
    *++yyvsp = yylval;  | 
    ||
2367  | 
    goto yyloop;  | 
    ||
2368  | 
    ✓✗ | 16  | 
    }  | 
    
2369  | 
    16  | 
    else  | 
    |
2370  | 
    16  | 
                { | 
    |
2371  | 
    #if YYDEBUG  | 
    ||
2372  | 
    if (yydebug)  | 
    ||
2373  | 
                        printf("%sdebug: error recovery discarding state %d\n", | 
    ||
2374  | 
    YYPREFIX, *yyssp);  | 
    ||
2375  | 
    #endif  | 
    ||
2376  | 
    ✓✗ | 44  | 
    if (yyssp <= yyss) goto yyabort;  | 
    
2377  | 
    --yyssp;  | 
    ||
2378  | 
    --yyvsp;  | 
    ||
2379  | 
    }  | 
    ||
2380  | 
    }  | 
    ||
2381  | 
    }  | 
    ||
2382  | 
    else  | 
    ||
2383  | 
        { | 
    ||
2384  | 
    if (yychar == 0) goto yyabort;  | 
    ||
2385  | 
    #if YYDEBUG  | 
    ||
2386  | 
    if (yydebug)  | 
    ||
2387  | 
    44  | 
            { | 
    |
2388  | 
    44  | 
    yys = 0;  | 
    |
2389  | 
    if (yychar <= YYMAXTOKEN) yys = yyname[yychar];  | 
    ||
2390  | 
    if (!yys) yys = "illegal-symbol";  | 
    ||
2391  | 
                printf("%sdebug: state %d, error recovery discards token %d (%s)\n", | 
    ||
2392  | 
    YYPREFIX, yystate, yychar, yys);  | 
    ||
2393  | 
    }  | 
    ||
2394  | 
    #endif  | 
    ||
2395  | 
    yychar = (-1);  | 
    ||
2396  | 
    42816  | 
    goto yyloop;  | 
    |
2397  | 
    ✓✓ | 42816  | 
    }  | 
    
2398  | 
    28884  | 
    yyreduce:  | 
    |
2399  | 
    #if YYDEBUG  | 
    ||
2400  | 
    13932  | 
    if (yydebug)  | 
    |
2401  | 
    ✓✗✗✓ ✓✓✓✗ ✗✗✓✓ ✓✗✗✗ ✗✗✓✗ ✗✗✗✓ ✗✓✗✗ ✗✗✓✗ ✗✗✗✗ ✗✗✗✗ ✗✓✗✗ ✓✓✓✗ ✓✓✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✓✓✓ ✓✓✓✗ ✗✗✗✗ ✓✗✓✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✓ ✓✓✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✗✓ ✓✓✓✓ ✗✓✓✗ ✓✗✓✓ ✗✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✓✗✗ ✓✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✓ ✗✗✗✗ ✓✓✗✗ ✗✗✓✓ ✗✗✗✗ ✓  | 
    62044  | 
            printf("%sdebug: state %d, reducing by rule %d (%s)\n", | 
    
2402  | 
    YYPREFIX, yystate, yyn, yyrule[yyn]);  | 
    ||
2403  | 
    #endif  | 
    ||
2404  | 
    yym = yylen[yyn];  | 
    ||
2405  | 
    if (yym)  | 
    ||
2406  | 
    yyval = yyvsp[1-yym];  | 
    ||
2407  | 
    else  | 
    ||
2408  | 
    memset(&yyval, 0, sizeof yyval);  | 
    ||
2409  | 
    switch (yyn)  | 
    ||
2410  | 
        { | 
    ||
2411  | 
    case 11:  | 
    ||
2412  | 
    #line 205 "parse.y"  | 
    ||
2413  | 
    { file->errors++; } | 
    ||
2414  | 
    break;  | 
    ||
2415  | 
    case 12:  | 
    ||
2416  | 
    #line 208 "parse.y"  | 
    ||
2417  | 
    { | 
    ||
2418  | 
    struct file *nfile;  | 
    ||
2419  | 
    |||
2420  | 
    			if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL) { | 
    ||
2421  | 
    				yyerror("failed to include file %s", yyvsp[0].v.string); | 
    ||
2422  | 
    free(yyvsp[0].v.string);  | 
    ||
2423  | 
    YYERROR;  | 
    ||
2424  | 
    }  | 
    ||
2425  | 
    free(yyvsp[0].v.string);  | 
    ||
2426  | 
    |||
2427  | 
    file = nfile;  | 
    ||
2428  | 
    			lungetc('\n'); | 
    ||
2429  | 
    }  | 
    ||
2430  | 
    break;  | 
    ||
2431  | 
    case 13:  | 
    ||
2432  | 
    #line 223 "parse.y"  | 
    ||
2433  | 
    { | 
    ||
2434  | 
    			log_warnx("%s:%d: %s", | 
    ||
2435  | 
    file->name, yylval.lineno,  | 
    ||
2436  | 
    "please use the \"tls\" keyword"  | 
    ||
2437  | 
    " instead of \"ssl\"");  | 
    ||
2438  | 
    }  | 
    ||
2439  | 
    break;  | 
    ||
2440  | 
    case 15:  | 
    ||
2441  | 
    #line 232 "parse.y"  | 
    ||
2442  | 
    { yyval.v.number = 0; } | 
    ||
2443  | 
    break;  | 
    ||
2444  | 
    case 16:  | 
    ||
2445  | 
    #line 233 "parse.y"  | 
    ||
2446  | 
    { yyval.v.number = 1; } | 
    ||
2447  | 
    break;  | 
    ||
2448  | 
    case 17:  | 
    ||
2449  | 
    #line 236 "parse.y"  | 
    ||
2450  | 
    { yyval.v.number = 0; } | 
    ||
2451  | 
    break;  | 
    ||
2452  | 
    case 18:  | 
    ||
2453  | 
    #line 237 "parse.y"  | 
    ||
2454  | 
    { yyval.v.number = 1; } | 
    ||
2455  | 
    break;  | 
    ||
2456  | 
    case 19:  | 
    ||
2457  | 
    #line 240 "parse.y"  | 
    ||
2458  | 
    { | 
    ||
2459  | 
    			if (strcmp("https", yyvsp[0].v.string) == 0) { | 
    ||
2460  | 
    yyval.v.number = 1;  | 
    ||
2461  | 
    			} else if (strcmp("http", yyvsp[0].v.string) == 0) { | 
    ||
2462  | 
    yyval.v.number = 0;  | 
    ||
2463  | 
    			} else { | 
    ||
2464  | 
    				yyerror("invalid check type: %s", yyvsp[0].v.string); | 
    ||
2465  | 
    free(yyvsp[0].v.string);  | 
    ||
2466  | 
    YYERROR;  | 
    ||
2467  | 
    }  | 
    ||
2468  | 
    free(yyvsp[0].v.string);  | 
    ||
2469  | 
    }  | 
    ||
2470  | 
    break;  | 
    ||
2471  | 
    case 20:  | 
    ||
2472  | 
    #line 254 "parse.y"  | 
    ||
2473  | 
    { | 
    ||
2474  | 
    			yyval.v.string = strdup(""); | 
    ||
2475  | 
    if (yyval.v.string == NULL)  | 
    ||
2476  | 
    				fatal("calloc"); | 
    ||
2477  | 
    }  | 
    ||
2478  | 
    break;  | 
    ||
2479  | 
    case 21:  | 
    ||
2480  | 
    #line 259 "parse.y"  | 
    ||
2481  | 
    { | 
    ||
2482  | 
    if (asprintf(&yyval.v.string, "Host: %s\r\nConnection: close\r\n",  | 
    ||
2483  | 
    yyvsp[0].v.string) == -1)  | 
    ||
2484  | 
    				fatal("asprintf"); | 
    ||
2485  | 
    }  | 
    ||
2486  | 
    break;  | 
    ||
2487  | 
    case 22:  | 
    ||
2488  | 
    #line 266 "parse.y"  | 
    ||
2489  | 
    { yyval.v.number = RELAY_PROTO_TCP; } | 
    ||
2490  | 
    break;  | 
    ||
2491  | 
    case 23:  | 
    ||
2492  | 
    #line 267 "parse.y"  | 
    ||
2493  | 
    { yyval.v.number = RELAY_PROTO_TCP; } | 
    ||
2494  | 
    break;  | 
    ||
2495  | 
    case 24:  | 
    ||
2496  | 
    #line 268 "parse.y"  | 
    ||
2497  | 
    { | 
    ||
2498  | 
    			if (strcmp("http", yyvsp[0].v.string) == 0) { | 
    ||
2499  | 
    yyval.v.number = RELAY_PROTO_HTTP;  | 
    ||
2500  | 
    			} else if (strcmp("dns", yyvsp[0].v.string) == 0) { | 
    ||
2501  | 
    yyval.v.number = RELAY_PROTO_DNS;  | 
    ||
2502  | 
    			} else { | 
    ||
2503  | 
    				yyerror("invalid protocol type: %s", yyvsp[0].v.string); | 
    ||
2504  | 
    free(yyvsp[0].v.string);  | 
    ||
2505  | 
    YYERROR;  | 
    ||
2506  | 
    }  | 
    ||
2507  | 
    free(yyvsp[0].v.string);  | 
    ||
2508  | 
    }  | 
    ||
2509  | 
    break;  | 
    ||
2510  | 
    case 25:  | 
    ||
2511  | 
    #line 282 "parse.y"  | 
    ||
2512  | 
    { yyval.v.number = IPPROTO_TCP; } | 
    ||
2513  | 
    break;  | 
    ||
2514  | 
    case 26:  | 
    ||
2515  | 
    #line 283 "parse.y"  | 
    ||
2516  | 
    { yyval.v.number = IPPROTO_TCP; } | 
    ||
2517  | 
    break;  | 
    ||
2518  | 
    case 27:  | 
    ||
2519  | 
    #line 284 "parse.y"  | 
    ||
2520  | 
    { | 
    ||
2521  | 
    struct protoent *p;  | 
    ||
2522  | 
    |||
2523  | 
    			if ((p = getprotobyname(yyvsp[0].v.string)) == NULL) { | 
    ||
2524  | 
    				yyerror("invalid protocol: %s", yyvsp[0].v.string); | 
    ||
2525  | 
    free(yyvsp[0].v.string);  | 
    ||
2526  | 
    YYERROR;  | 
    ||
2527  | 
    }  | 
    ||
2528  | 
    free(yyvsp[0].v.string);  | 
    ||
2529  | 
    |||
2530  | 
    yyval.v.number = p->p_proto;  | 
    ||
2531  | 
    }  | 
    ||
2532  | 
    break;  | 
    ||
2533  | 
    case 32:  | 
    ||
2534  | 
    #line 307 "parse.y"  | 
    ||
2535  | 
    { | 
    ||
2536  | 
    if ((proto->style = strdup(yyvsp[0].v.string)) == NULL)  | 
    ||
2537  | 
    				fatal("out of memory"); | 
    ||
2538  | 
    free(yyvsp[0].v.string);  | 
    ||
2539  | 
    }  | 
    ||
2540  | 
    break;  | 
    ||
2541  | 
    case 33:  | 
    ||
2542  | 
    #line 314 "parse.y"  | 
    ||
2543  | 
    { | 
    ||
2544  | 
    char *a, *b;  | 
    ||
2545  | 
    int p[2];  | 
    ||
2546  | 
    |||
2547  | 
    p[0] = p[1] = 0;  | 
    ||
2548  | 
    |||
2549  | 
    a = yyvsp[0].v.string;  | 
    ||
2550  | 
    b = strchr(yyvsp[0].v.string, ':');  | 
    ||
2551  | 
    if (b == NULL)  | 
    ||
2552  | 
    yyval.v.port.op = PF_OP_EQ;  | 
    ||
2553  | 
    			else { | 
    ||
2554  | 
    *b++ = '\0';  | 
    ||
2555  | 
    				if ((p[1] = getservice(b)) == -1) { | 
    ||
2556  | 
    free(yyvsp[0].v.string);  | 
    ||
2557  | 
    YYERROR;  | 
    ||
2558  | 
    }  | 
    ||
2559  | 
    yyval.v.port.op = PF_OP_RRG;  | 
    ||
2560  | 
    }  | 
    ||
2561  | 
    			if ((p[0] = getservice(a)) == -1) { | 
    ||
2562  | 
    free(yyvsp[0].v.string);  | 
    ||
2563  | 
    YYERROR;  | 
    ||
2564  | 
    }  | 
    ||
2565  | 
    yyval.v.port.val[0] = p[0];  | 
    ||
2566  | 
    yyval.v.port.val[1] = p[1];  | 
    ||
2567  | 
    free(yyvsp[0].v.string);  | 
    ||
2568  | 
    }  | 
    ||
2569  | 
    break;  | 
    ||
2570  | 
    case 34:  | 
    ||
2571  | 
    #line 340 "parse.y"  | 
    ||
2572  | 
    { | 
    ||
2573  | 
    			if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > (int)USHRT_MAX) { | 
    ||
2574  | 
    				yyerror("invalid port: %d", yyvsp[0].v.number); | 
    ||
2575  | 
    YYERROR;  | 
    ||
2576  | 
    }  | 
    ||
2577  | 
    yyval.v.port.val[0] = htons(yyvsp[0].v.number);  | 
    ||
2578  | 
    yyval.v.port.op = PF_OP_EQ;  | 
    ||
2579  | 
    }  | 
    ||
2580  | 
    break;  | 
    ||
2581  | 
    case 35:  | 
    ||
2582  | 
    #line 350 "parse.y"  | 
    ||
2583  | 
    { | 
    ||
2584  | 
    char *s = yyvsp[-2].v.string;  | 
    ||
2585  | 
    			while (*s++) { | 
    ||
2586  | 
    				if (isspace((unsigned char)*s)) { | 
    ||
2587  | 
    					yyerror("macro name cannot contain " | 
    ||
2588  | 
    "whitespace");  | 
    ||
2589  | 
    YYERROR;  | 
    ||
2590  | 
    }  | 
    ||
2591  | 
    }  | 
    ||
2592  | 
    if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)  | 
    ||
2593  | 
    				fatal("cannot store variable"); | 
    ||
2594  | 
    free(yyvsp[-2].v.string);  | 
    ||
2595  | 
    free(yyvsp[0].v.string);  | 
    ||
2596  | 
    }  | 
    ||
2597  | 
    break;  | 
    ||
2598  | 
    case 36:  | 
    ||
2599  | 
    #line 366 "parse.y"  | 
    ||
2600  | 
    { | 
    ||
2601  | 
    table->sendbuf = NULL;  | 
    ||
2602  | 
    }  | 
    ||
2603  | 
    break;  | 
    ||
2604  | 
    case 37:  | 
    ||
2605  | 
    #line 369 "parse.y"  | 
    ||
2606  | 
    { | 
    ||
2607  | 
    table->sendbuf = strdup(yyvsp[0].v.string);  | 
    ||
2608  | 
    if (table->sendbuf == NULL)  | 
    ||
2609  | 
    				fatal("out of memory"); | 
    ||
2610  | 
    free(yyvsp[0].v.string);  | 
    ||
2611  | 
    }  | 
    ||
2612  | 
    break;  | 
    ||
2613  | 
    case 38:  | 
    ||
2614  | 
    #line 377 "parse.y"  | 
    ||
2615  | 
    { | 
    ||
2616  | 
    			if ((conf->sc_conf.interval.tv_sec = yyvsp[0].v.number) < 0) { | 
    ||
2617  | 
    				yyerror("invalid interval: %d", yyvsp[0].v.number); | 
    ||
2618  | 
    YYERROR;  | 
    ||
2619  | 
    }  | 
    ||
2620  | 
    }  | 
    ||
2621  | 
    break;  | 
    ||
2622  | 
    case 39:  | 
    ||
2623  | 
    #line 383 "parse.y"  | 
    ||
2624  | 
    { | 
    ||
2625  | 
    conf->sc_conf.opts |= yyvsp[0].v.number;  | 
    ||
2626  | 
    }  | 
    ||
2627  | 
    break;  | 
    ||
2628  | 
    case 40:  | 
    ||
2629  | 
    #line 386 "parse.y"  | 
    ||
2630  | 
    { | 
    ||
2631  | 
    bcopy(&yyvsp[0].v.tv, &conf->sc_conf.timeout,  | 
    ||
2632  | 
    sizeof(struct timeval));  | 
    ||
2633  | 
    }  | 
    ||
2634  | 
    break;  | 
    ||
2635  | 
    case 41:  | 
    ||
2636  | 
    #line 390 "parse.y"  | 
    ||
2637  | 
    { | 
    ||
2638  | 
    			if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > PROC_MAX_INSTANCES) { | 
    ||
2639  | 
    				yyerror("invalid number of preforked " | 
    ||
2640  | 
    "relays: %d", yyvsp[0].v.number);  | 
    ||
2641  | 
    YYERROR;  | 
    ||
2642  | 
    }  | 
    ||
2643  | 
    conf->sc_conf.prefork_relay = yyvsp[0].v.number;  | 
    ||
2644  | 
    }  | 
    ||
2645  | 
    break;  | 
    ||
2646  | 
    case 42:  | 
    ||
2647  | 
    #line 398 "parse.y"  | 
    ||
2648  | 
    { | 
    ||
2649  | 
    conf->sc_conf.flags |= F_SNMP;  | 
    ||
2650  | 
    if (yyvsp[-1].v.number)  | 
    ||
2651  | 
    conf->sc_conf.flags |= F_SNMP_TRAPONLY;  | 
    ||
2652  | 
    			if (yyvsp[0].v.string) { | 
    ||
2653  | 
    if (strlcpy(conf->sc_conf.snmp_path,  | 
    ||
2654  | 
    yyvsp[0].v.string, sizeof(conf->sc_conf.snmp_path)) >=  | 
    ||
2655  | 
    				    sizeof(conf->sc_conf.snmp_path)) { | 
    ||
2656  | 
    					yyerror("snmp path truncated"); | 
    ||
2657  | 
    free(yyvsp[0].v.string);  | 
    ||
2658  | 
    YYERROR;  | 
    ||
2659  | 
    }  | 
    ||
2660  | 
    free(yyvsp[0].v.string);  | 
    ||
2661  | 
    } else  | 
    ||
2662  | 
    (void)strlcpy(conf->sc_conf.snmp_path,  | 
    ||
2663  | 
    AGENTX_SOCKET,  | 
    ||
2664  | 
    sizeof(conf->sc_conf.snmp_path));  | 
    ||
2665  | 
    }  | 
    ||
2666  | 
    break;  | 
    ||
2667  | 
    case 43:  | 
    ||
2668  | 
    #line 418 "parse.y"  | 
    ||
2669  | 
    { yyval.v.number = 0; } | 
    ||
2670  | 
    break;  | 
    ||
2671  | 
    case 44:  | 
    ||
2672  | 
    #line 419 "parse.y"  | 
    ||
2673  | 
    { yyval.v.number = 1; } | 
    ||
2674  | 
    break;  | 
    ||
2675  | 
    case 45:  | 
    ||
2676  | 
    #line 421 "parse.y"  | 
    ||
2677  | 
    { yyval.v.number = RELAYD_OPT_LOGUPDATE; } | 
    ||
2678  | 
    break;  | 
    ||
2679  | 
    case 46:  | 
    ||
2680  | 
    #line 422 "parse.y"  | 
    ||
2681  | 
    { yyval.v.number = RELAYD_OPT_LOGALL; } | 
    ||
2682  | 
    break;  | 
    ||
2683  | 
    case 47:  | 
    ||
2684  | 
    #line 425 "parse.y"  | 
    ||
2685  | 
    { | 
    ||
2686  | 
    struct rdr *srv;  | 
    ||
2687  | 
    |||
2688  | 
    conf->sc_conf.flags |= F_NEEDPF;  | 
    ||
2689  | 
    |||
2690  | 
    			if (!loadcfg) { | 
    ||
2691  | 
    free(yyvsp[0].v.string);  | 
    ||
2692  | 
    YYACCEPT;  | 
    ||
2693  | 
    }  | 
    ||
2694  | 
    |||
2695  | 
    TAILQ_FOREACH(srv, conf->sc_rdrs, entry)  | 
    ||
2696  | 
    if (!strcmp(srv->conf.name, yyvsp[0].v.string))  | 
    ||
2697  | 
    break;  | 
    ||
2698  | 
    			if (srv != NULL) { | 
    ||
2699  | 
    				yyerror("redirection %s defined twice", yyvsp[0].v.string); | 
    ||
2700  | 
    free(yyvsp[0].v.string);  | 
    ||
2701  | 
    YYERROR;  | 
    ||
2702  | 
    }  | 
    ||
2703  | 
    if ((srv = calloc(1, sizeof (*srv))) == NULL)  | 
    ||
2704  | 
    				fatal("out of memory"); | 
    ||
2705  | 
    |||
2706  | 
    if (strlcpy(srv->conf.name, yyvsp[0].v.string,  | 
    ||
2707  | 
    sizeof(srv->conf.name)) >=  | 
    ||
2708  | 
    			    sizeof(srv->conf.name)) { | 
    ||
2709  | 
    				yyerror("redirection name truncated"); | 
    ||
2710  | 
    free(yyvsp[0].v.string);  | 
    ||
2711  | 
    free(srv);  | 
    ||
2712  | 
    YYERROR;  | 
    ||
2713  | 
    }  | 
    ||
2714  | 
    free(yyvsp[0].v.string);  | 
    ||
2715  | 
    srv->conf.id = ++last_rdr_id;  | 
    ||
2716  | 
    srv->conf.timeout.tv_sec = RELAY_TIMEOUT;  | 
    ||
2717  | 
    			if (last_rdr_id == INT_MAX) { | 
    ||
2718  | 
    				yyerror("too many redirections defined"); | 
    ||
2719  | 
    free(srv);  | 
    ||
2720  | 
    YYERROR;  | 
    ||
2721  | 
    }  | 
    ||
2722  | 
    rdr = srv;  | 
    ||
2723  | 
    }  | 
    ||
2724  | 
    break;  | 
    ||
2725  | 
    case 48:  | 
    ||
2726  | 
    #line 463 "parse.y"  | 
    ||
2727  | 
    { | 
    ||
2728  | 
    			if (rdr->table == NULL) { | 
    ||
2729  | 
    				yyerror("redirection %s has no table", | 
    ||
2730  | 
    rdr->conf.name);  | 
    ||
2731  | 
    YYERROR;  | 
    ||
2732  | 
    }  | 
    ||
2733  | 
    			if (TAILQ_EMPTY(&rdr->virts)) { | 
    ||
2734  | 
    				yyerror("redirection %s has no virtual ip", | 
    ||
2735  | 
    rdr->conf.name);  | 
    ||
2736  | 
    YYERROR;  | 
    ||
2737  | 
    }  | 
    ||
2738  | 
    conf->sc_rdrcount++;  | 
    ||
2739  | 
    			if (rdr->backup == NULL) { | 
    ||
2740  | 
    rdr->conf.backup_id =  | 
    ||
2741  | 
    conf->sc_empty_table.conf.id;  | 
    ||
2742  | 
    rdr->backup = &conf->sc_empty_table;  | 
    ||
2743  | 
    } else if (rdr->backup->conf.port !=  | 
    ||
2744  | 
    			    rdr->table->conf.port) { | 
    ||
2745  | 
    				yyerror("redirection %s uses two different " | 
    ||
2746  | 
    "ports for its table and backup table",  | 
    ||
2747  | 
    rdr->conf.name);  | 
    ||
2748  | 
    YYERROR;  | 
    ||
2749  | 
    }  | 
    ||
2750  | 
    if (!(rdr->conf.flags & F_DISABLE))  | 
    ||
2751  | 
    rdr->conf.flags |= F_ADD;  | 
    ||
2752  | 
    TAILQ_INSERT_TAIL(conf->sc_rdrs, rdr, entry);  | 
    ||
2753  | 
    tableport = 0;  | 
    ||
2754  | 
    rdr = NULL;  | 
    ||
2755  | 
    }  | 
    ||
2756  | 
    break;  | 
    ||
2757  | 
    case 51:  | 
    ||
2758  | 
    #line 498 "parse.y"  | 
    ||
2759  | 
    { | 
    ||
2760  | 
    			if (hashkey != NULL) { | 
    ||
2761  | 
    memcpy(&rdr->conf.key,  | 
    ||
2762  | 
    hashkey, sizeof(rdr->conf.key));  | 
    ||
2763  | 
    rdr->conf.flags |= F_HASHKEY;  | 
    ||
2764  | 
    free(hashkey);  | 
    ||
2765  | 
    hashkey = NULL;  | 
    ||
2766  | 
    }  | 
    ||
2767  | 
    |||
2768  | 
    			switch (yyvsp[-3].v.number) { | 
    ||
2769  | 
    case FWD_NORMAL:  | 
    ||
2770  | 
    if (yyvsp[0].v.string == NULL)  | 
    ||
2771  | 
    break;  | 
    ||
2772  | 
    				yyerror("superfluous interface"); | 
    ||
2773  | 
    free(yyvsp[0].v.string);  | 
    ||
2774  | 
    YYERROR;  | 
    ||
2775  | 
    case FWD_ROUTE:  | 
    ||
2776  | 
    if (yyvsp[0].v.string != NULL)  | 
    ||
2777  | 
    break;  | 
    ||
2778  | 
    				yyerror("missing interface to route to"); | 
    ||
2779  | 
    free(yyvsp[0].v.string);  | 
    ||
2780  | 
    YYERROR;  | 
    ||
2781  | 
    case FWD_TRANS:  | 
    ||
2782  | 
    				yyerror("no transparent forward here"); | 
    ||
2783  | 
    if (yyvsp[0].v.string != NULL)  | 
    ||
2784  | 
    free(yyvsp[0].v.string);  | 
    ||
2785  | 
    YYERROR;  | 
    ||
2786  | 
    }  | 
    ||
2787  | 
    			if (yyvsp[0].v.string != NULL) { | 
    ||
2788  | 
    if (strlcpy(yyvsp[-1].v.table->conf.ifname, yyvsp[0].v.string,  | 
    ||
2789  | 
    sizeof(yyvsp[-1].v.table->conf.ifname)) >=  | 
    ||
2790  | 
    				    sizeof(yyvsp[-1].v.table->conf.ifname)) { | 
    ||
2791  | 
    					yyerror("interface name truncated"); | 
    ||
2792  | 
    free(yyvsp[0].v.string);  | 
    ||
2793  | 
    YYERROR;  | 
    ||
2794  | 
    }  | 
    ||
2795  | 
    free(yyvsp[0].v.string);  | 
    ||
2796  | 
    }  | 
    ||
2797  | 
    |||
2798  | 
    			if (yyvsp[-1].v.table->conf.check == CHECK_NOCHECK) { | 
    ||
2799  | 
    				yyerror("table %s has no check", yyvsp[-1].v.table->conf.name); | 
    ||
2800  | 
    purge_table(conf, conf->sc_tables, yyvsp[-1].v.table);  | 
    ||
2801  | 
    YYERROR;  | 
    ||
2802  | 
    }  | 
    ||
2803  | 
    			if (rdr->backup) { | 
    ||
2804  | 
    				yyerror("only one backup table is allowed"); | 
    ||
2805  | 
    purge_table(conf, conf->sc_tables, yyvsp[-1].v.table);  | 
    ||
2806  | 
    YYERROR;  | 
    ||
2807  | 
    }  | 
    ||
2808  | 
    			if (rdr->table) { | 
    ||
2809  | 
    rdr->backup = yyvsp[-1].v.table;  | 
    ||
2810  | 
    rdr->conf.backup_id = yyvsp[-1].v.table->conf.id;  | 
    ||
2811  | 
    				if (dstmode != rdr->conf.mode) { | 
    ||
2812  | 
    					yyerror("backup table for %s with " | 
    ||
2813  | 
    "different mode", rdr->conf.name);  | 
    ||
2814  | 
    YYERROR;  | 
    ||
2815  | 
    }  | 
    ||
2816  | 
    			} else { | 
    ||
2817  | 
    rdr->table = yyvsp[-1].v.table;  | 
    ||
2818  | 
    rdr->conf.table_id = yyvsp[-1].v.table->conf.id;  | 
    ||
2819  | 
    rdr->conf.mode = dstmode;  | 
    ||
2820  | 
    }  | 
    ||
2821  | 
    yyvsp[-1].v.table->conf.fwdmode = yyvsp[-3].v.number;  | 
    ||
2822  | 
    yyvsp[-1].v.table->conf.rdrid = rdr->conf.id;  | 
    ||
2823  | 
    yyvsp[-1].v.table->conf.flags |= F_USED;  | 
    ||
2824  | 
    }  | 
    ||
2825  | 
    break;  | 
    ||
2826  | 
    case 52:  | 
    ||
2827  | 
    #line 564 "parse.y"  | 
    ||
2828  | 
    { | 
    ||
2829  | 
    if (host(yyvsp[-3].v.string, &rdr->virts,  | 
    ||
2830  | 
    			    SRV_MAX_VIRTS, &yyvsp[-1].v.port, yyvsp[0].v.string, yyvsp[-2].v.number) <= 0) { | 
    ||
2831  | 
    				yyerror("invalid virtual ip: %s", yyvsp[-3].v.string); | 
    ||
2832  | 
    free(yyvsp[-3].v.string);  | 
    ||
2833  | 
    free(yyvsp[0].v.string);  | 
    ||
2834  | 
    YYERROR;  | 
    ||
2835  | 
    }  | 
    ||
2836  | 
    free(yyvsp[-3].v.string);  | 
    ||
2837  | 
    free(yyvsp[0].v.string);  | 
    ||
2838  | 
    if (rdr->conf.port == 0)  | 
    ||
2839  | 
    rdr->conf.port = yyvsp[-1].v.port.val[0];  | 
    ||
2840  | 
    tableport = rdr->conf.port;  | 
    ||
2841  | 
    }  | 
    ||
2842  | 
    break;  | 
    ||
2843  | 
    case 53:  | 
    ||
2844  | 
    #line 578 "parse.y"  | 
    ||
2845  | 
    { rdr->conf.flags |= F_DISABLE; } | 
    ||
2846  | 
    break;  | 
    ||
2847  | 
    case 54:  | 
    ||
2848  | 
    #line 579 "parse.y"  | 
    ||
2849  | 
    { rdr->conf.flags |= F_STICKY; } | 
    ||
2850  | 
    break;  | 
    ||
2851  | 
    case 55:  | 
    ||
2852  | 
    #line 580 "parse.y"  | 
    ||
2853  | 
    { | 
    ||
2854  | 
    conf->sc_conf.flags |= F_NEEDPF;  | 
    ||
2855  | 
    if (strlcpy(rdr->conf.tag, yyvsp[0].v.string,  | 
    ||
2856  | 
    sizeof(rdr->conf.tag)) >=  | 
    ||
2857  | 
    			    sizeof(rdr->conf.tag)) { | 
    ||
2858  | 
    				yyerror("redirection tag name truncated"); | 
    ||
2859  | 
    free(yyvsp[0].v.string);  | 
    ||
2860  | 
    YYERROR;  | 
    ||
2861  | 
    }  | 
    ||
2862  | 
    if (yyvsp[-2].v.number)  | 
    ||
2863  | 
    rdr->conf.flags |= F_MATCH;  | 
    ||
2864  | 
    free(yyvsp[0].v.string);  | 
    ||
2865  | 
    }  | 
    ||
2866  | 
    break;  | 
    ||
2867  | 
    case 56:  | 
    ||
2868  | 
    #line 593 "parse.y"  | 
    ||
2869  | 
    { | 
    ||
2870  | 
    			if ((rdr->conf.timeout.tv_sec = yyvsp[0].v.number) < 0) { | 
    ||
2871  | 
    				yyerror("invalid timeout: %lld", yyvsp[0].v.number); | 
    ||
2872  | 
    YYERROR;  | 
    ||
2873  | 
    }  | 
    ||
2874  | 
    			if (rdr->conf.timeout.tv_sec > INT_MAX) { | 
    ||
2875  | 
    				yyerror("timeout too large: %lld", yyvsp[0].v.number); | 
    ||
2876  | 
    YYERROR;  | 
    ||
2877  | 
    }  | 
    ||
2878  | 
    }  | 
    ||
2879  | 
    break;  | 
    ||
2880  | 
    case 58:  | 
    ||
2881  | 
    #line 606 "parse.y"  | 
    ||
2882  | 
    { yyval.v.number = 0; } | 
    ||
2883  | 
    break;  | 
    ||
2884  | 
    case 59:  | 
    ||
2885  | 
    #line 607 "parse.y"  | 
    ||
2886  | 
    { yyval.v.number = 1; } | 
    ||
2887  | 
    break;  | 
    ||
2888  | 
    case 60:  | 
    ||
2889  | 
    #line 610 "parse.y"  | 
    ||
2890  | 
    { yyval.v.number = FWD_NORMAL; } | 
    ||
2891  | 
    break;  | 
    ||
2892  | 
    case 61:  | 
    ||
2893  | 
    #line 611 "parse.y"  | 
    ||
2894  | 
    { yyval.v.number = FWD_ROUTE; } | 
    ||
2895  | 
    break;  | 
    ||
2896  | 
    case 62:  | 
    ||
2897  | 
    #line 612 "parse.y"  | 
    ||
2898  | 
    { yyval.v.number = FWD_TRANS; } | 
    ||
2899  | 
    break;  | 
    ||
2900  | 
    case 63:  | 
    ||
2901  | 
    #line 615 "parse.y"  | 
    ||
2902  | 
    { | 
    ||
2903  | 
    			if (strlen(yyvsp[-1].v.string) >= TABLE_NAME_SIZE) { | 
    ||
2904  | 
    				yyerror("invalid table name"); | 
    ||
2905  | 
    free(yyvsp[-1].v.string);  | 
    ||
2906  | 
    YYERROR;  | 
    ||
2907  | 
    }  | 
    ||
2908  | 
    yyval.v.string = yyvsp[-1].v.string;  | 
    ||
2909  | 
    }  | 
    ||
2910  | 
    break;  | 
    ||
2911  | 
    case 64:  | 
    ||
2912  | 
    #line 625 "parse.y"  | 
    ||
2913  | 
    { | 
    ||
2914  | 
    struct table *tb;  | 
    ||
2915  | 
    |||
2916  | 
    			if (!loadcfg) { | 
    ||
2917  | 
    free(yyvsp[0].v.string);  | 
    ||
2918  | 
    YYACCEPT;  | 
    ||
2919  | 
    }  | 
    ||
2920  | 
    |||
2921  | 
    TAILQ_FOREACH(tb, conf->sc_tables, entry)  | 
    ||
2922  | 
    if (!strcmp(tb->conf.name, yyvsp[0].v.string))  | 
    ||
2923  | 
    break;  | 
    ||
2924  | 
    			if (tb != NULL) { | 
    ||
2925  | 
    				yyerror("table %s defined twice", yyvsp[0].v.string); | 
    ||
2926  | 
    free(yyvsp[0].v.string);  | 
    ||
2927  | 
    YYERROR;  | 
    ||
2928  | 
    }  | 
    ||
2929  | 
    |||
2930  | 
    if ((tb = calloc(1, sizeof (*tb))) == NULL)  | 
    ||
2931  | 
    				fatal("out of memory"); | 
    ||
2932  | 
    |||
2933  | 
    if (strlcpy(tb->conf.name, yyvsp[0].v.string,  | 
    ||
2934  | 
    			    sizeof(tb->conf.name)) >= sizeof(tb->conf.name)) { | 
    ||
2935  | 
    				yyerror("table name truncated"); | 
    ||
2936  | 
    free(yyvsp[0].v.string);  | 
    ||
2937  | 
    YYERROR;  | 
    ||
2938  | 
    }  | 
    ||
2939  | 
    free(yyvsp[0].v.string);  | 
    ||
2940  | 
    |||
2941  | 
    tb->conf.id = 0; /* will be set later */  | 
    ||
2942  | 
    bcopy(&conf->sc_conf.timeout, &tb->conf.timeout,  | 
    ||
2943  | 
    sizeof(struct timeval));  | 
    ||
2944  | 
    TAILQ_INIT(&tb->hosts);  | 
    ||
2945  | 
    table = tb;  | 
    ||
2946  | 
    dstmode = RELAY_DSTMODE_DEFAULT;  | 
    ||
2947  | 
    }  | 
    ||
2948  | 
    break;  | 
    ||
2949  | 
    case 65:  | 
    ||
2950  | 
    #line 659 "parse.y"  | 
    ||
2951  | 
    { | 
    ||
2952  | 
    			if (TAILQ_EMPTY(&table->hosts)) { | 
    ||
2953  | 
    				yyerror("table %s has no hosts", | 
    ||
2954  | 
    table->conf.name);  | 
    ||
2955  | 
    YYERROR;  | 
    ||
2956  | 
    }  | 
    ||
2957  | 
    conf->sc_tablecount++;  | 
    ||
2958  | 
    TAILQ_INSERT_TAIL(conf->sc_tables, table, entry);  | 
    ||
2959  | 
    }  | 
    ||
2960  | 
    break;  | 
    ||
2961  | 
    case 68:  | 
    ||
2962  | 
    #line 674 "parse.y"  | 
    ||
2963  | 
    { table->conf.flags |= F_DISABLE; } | 
    ||
2964  | 
    break;  | 
    ||
2965  | 
    case 72:  | 
    ||
2966  | 
    #line 682 "parse.y"  | 
    ||
2967  | 
    { | 
    ||
2968  | 
    yyvsp[0].v.host->conf.tableid = table->conf.id;  | 
    ||
2969  | 
    yyvsp[0].v.host->tablename = table->conf.name;  | 
    ||
2970  | 
    TAILQ_INSERT_TAIL(&table->hosts, yyvsp[0].v.host, entry);  | 
    ||
2971  | 
    }  | 
    ||
2972  | 
    break;  | 
    ||
2973  | 
    case 74:  | 
    ||
2974  | 
    #line 690 "parse.y"  | 
    ||
2975  | 
    { | 
    ||
2976  | 
    struct table *tb;  | 
    ||
2977  | 
    if ((tb = calloc(1, sizeof (*tb))) == NULL)  | 
    ||
2978  | 
    				fatal("out of memory"); | 
    ||
2979  | 
    if (strlcpy(tb->conf.name, yyvsp[0].v.string,  | 
    ||
2980  | 
    			    sizeof(tb->conf.name)) >= sizeof(tb->conf.name)) { | 
    ||
2981  | 
    				yyerror("table name truncated"); | 
    ||
2982  | 
    free(yyvsp[0].v.string);  | 
    ||
2983  | 
    YYERROR;  | 
    ||
2984  | 
    }  | 
    ||
2985  | 
    free(yyvsp[0].v.string);  | 
    ||
2986  | 
    table = tb;  | 
    ||
2987  | 
    dstmode = RELAY_DSTMODE_DEFAULT;  | 
    ||
2988  | 
    hashkey = NULL;  | 
    ||
2989  | 
    }  | 
    ||
2990  | 
    break;  | 
    ||
2991  | 
    case 75:  | 
    ||
2992  | 
    #line 704 "parse.y"  | 
    ||
2993  | 
    { | 
    ||
2994  | 
    struct table *tb;  | 
    ||
2995  | 
    if (table->conf.port == 0)  | 
    ||
2996  | 
    table->conf.port = tableport;  | 
    ||
2997  | 
    else  | 
    ||
2998  | 
    table->conf.flags |= F_PORT;  | 
    ||
2999  | 
    if ((tb = table_inherit(table)) == NULL)  | 
    ||
3000  | 
    YYERROR;  | 
    ||
3001  | 
    yyval.v.table = tb;  | 
    ||
3002  | 
    }  | 
    ||
3003  | 
    break;  | 
    ||
3004  | 
    case 79:  | 
    ||
3005  | 
    #line 721 "parse.y"  | 
    ||
3006  | 
    { | 
    ||
3007  | 
    			if (yyvsp[0].v.port.op != PF_OP_EQ) { | 
    ||
3008  | 
    				yyerror("invalid port"); | 
    ||
3009  | 
    YYERROR;  | 
    ||
3010  | 
    }  | 
    ||
3011  | 
    table->conf.port = yyvsp[0].v.port.val[0];  | 
    ||
3012  | 
    }  | 
    ||
3013  | 
    break;  | 
    ||
3014  | 
    case 80:  | 
    ||
3015  | 
    #line 728 "parse.y"  | 
    ||
3016  | 
    { | 
    ||
3017  | 
    bcopy(&yyvsp[0].v.tv, &table->conf.timeout,  | 
    ||
3018  | 
    sizeof(struct timeval));  | 
    ||
3019  | 
    }  | 
    ||
3020  | 
    break;  | 
    ||
3021  | 
    case 81:  | 
    ||
3022  | 
    #line 732 "parse.y"  | 
    ||
3023  | 
    { | 
    ||
3024  | 
    table->conf.flags |= F_DEMOTE;  | 
    ||
3025  | 
    if (strlcpy(table->conf.demote_group, yyvsp[0].v.string,  | 
    ||
3026  | 
    sizeof(table->conf.demote_group))  | 
    ||
3027  | 
    			    >= sizeof(table->conf.demote_group)) { | 
    ||
3028  | 
    				yyerror("yyparse: demote group name too long"); | 
    ||
3029  | 
    free(yyvsp[0].v.string);  | 
    ||
3030  | 
    YYERROR;  | 
    ||
3031  | 
    }  | 
    ||
3032  | 
    free(yyvsp[0].v.string);  | 
    ||
3033  | 
    if (carp_demote_init(table->conf.demote_group, 1)  | 
    ||
3034  | 
    			    == -1) { | 
    ||
3035  | 
    				yyerror("yyparse: error initializing group " | 
    ||
3036  | 
    "'%s'", table->conf.demote_group);  | 
    ||
3037  | 
    YYERROR;  | 
    ||
3038  | 
    }  | 
    ||
3039  | 
    }  | 
    ||
3040  | 
    break;  | 
    ||
3041  | 
    case 82:  | 
    ||
3042  | 
    #line 749 "parse.y"  | 
    ||
3043  | 
    { | 
    ||
3044  | 
    if (yyvsp[0].v.number < conf->sc_conf.interval.tv_sec ||  | 
    ||
3045  | 
    			    yyvsp[0].v.number % conf->sc_conf.interval.tv_sec) { | 
    ||
3046  | 
    				yyerror("table interval must be " | 
    ||
3047  | 
    "divisible by global interval");  | 
    ||
3048  | 
    YYERROR;  | 
    ||
3049  | 
    }  | 
    ||
3050  | 
    table->conf.skip_cnt =  | 
    ||
3051  | 
    (yyvsp[0].v.number / conf->sc_conf.interval.tv_sec) - 1;  | 
    ||
3052  | 
    }  | 
    ||
3053  | 
    break;  | 
    ||
3054  | 
    case 83:  | 
    ||
3055  | 
    #line 759 "parse.y"  | 
    ||
3056  | 
    { | 
    ||
3057  | 
    			switch (yyvsp[-1].v.number) { | 
    ||
3058  | 
    case RELAY_DSTMODE_LOADBALANCE:  | 
    ||
3059  | 
    case RELAY_DSTMODE_HASH:  | 
    ||
3060  | 
    case RELAY_DSTMODE_SRCHASH:  | 
    ||
3061  | 
    				if (hashkey != NULL) { | 
    ||
3062  | 
    					yyerror("key already specified"); | 
    ||
3063  | 
    free(hashkey);  | 
    ||
3064  | 
    YYERROR;  | 
    ||
3065  | 
    }  | 
    ||
3066  | 
    if ((hashkey = calloc(1,  | 
    ||
3067  | 
    sizeof(*hashkey))) == NULL)  | 
    ||
3068  | 
    					fatal("out of memory"); | 
    ||
3069  | 
    memcpy(hashkey, &yyvsp[0].v.key.key, sizeof(*hashkey));  | 
    ||
3070  | 
    break;  | 
    ||
3071  | 
    default:  | 
    ||
3072  | 
    				if (yyvsp[0].v.key.keyset) { | 
    ||
3073  | 
    					yyerror("key not supported by mode"); | 
    ||
3074  | 
    YYERROR;  | 
    ||
3075  | 
    }  | 
    ||
3076  | 
    hashkey = NULL;  | 
    ||
3077  | 
    break;  | 
    ||
3078  | 
    }  | 
    ||
3079  | 
    |||
3080  | 
    			switch (yyvsp[-1].v.number) { | 
    ||
3081  | 
    case RELAY_DSTMODE_LOADBALANCE:  | 
    ||
3082  | 
    case RELAY_DSTMODE_HASH:  | 
    ||
3083  | 
    				if (rdr != NULL) { | 
    ||
3084  | 
    					yyerror("mode not supported " | 
    ||
3085  | 
    "for redirections");  | 
    ||
3086  | 
    YYERROR;  | 
    ||
3087  | 
    }  | 
    ||
3088  | 
    /* FALLTHROUGH */  | 
    ||
3089  | 
    case RELAY_DSTMODE_RANDOM:  | 
    ||
3090  | 
    case RELAY_DSTMODE_ROUNDROBIN:  | 
    ||
3091  | 
    case RELAY_DSTMODE_SRCHASH:  | 
    ||
3092  | 
    dstmode = yyvsp[-1].v.number;  | 
    ||
3093  | 
    break;  | 
    ||
3094  | 
    case RELAY_DSTMODE_LEASTSTATES:  | 
    ||
3095  | 
    				if (rdr == NULL) { | 
    ||
3096  | 
    					yyerror("mode not supported " | 
    ||
3097  | 
    "for relays");  | 
    ||
3098  | 
    YYERROR;  | 
    ||
3099  | 
    }  | 
    ||
3100  | 
    dstmode = yyvsp[-1].v.number;  | 
    ||
3101  | 
    break;  | 
    ||
3102  | 
    }  | 
    ||
3103  | 
    }  | 
    ||
3104  | 
    break;  | 
    ||
3105  | 
    case 84:  | 
    ||
3106  | 
    #line 810 "parse.y"  | 
    ||
3107  | 
    { | 
    ||
3108  | 
    yyval.v.key.keyset = 0;  | 
    ||
3109  | 
    yyval.v.key.key.data[0] = arc4random();  | 
    ||
3110  | 
    yyval.v.key.key.data[1] = arc4random();  | 
    ||
3111  | 
    yyval.v.key.key.data[2] = arc4random();  | 
    ||
3112  | 
    yyval.v.key.key.data[3] = arc4random();  | 
    ||
3113  | 
    }  | 
    ||
3114  | 
    break;  | 
    ||
3115  | 
    case 85:  | 
    ||
3116  | 
    #line 817 "parse.y"  | 
    ||
3117  | 
    { | 
    ||
3118  | 
    /* manual key configuration */  | 
    ||
3119  | 
    yyval.v.key.keyset = 1;  | 
    ||
3120  | 
    |||
3121  | 
    			if (!strncmp(yyvsp[0].v.string, "0x", 2)) { | 
    ||
3122  | 
    				if (strlen(yyvsp[0].v.string) != 34) { | 
    ||
3123  | 
    free(yyvsp[0].v.string);  | 
    ||
3124  | 
    					yyerror("hex key must be 128 bits " | 
    ||
3125  | 
    "(32 hex digits) long");  | 
    ||
3126  | 
    YYERROR;  | 
    ||
3127  | 
    }  | 
    ||
3128  | 
    |||
3129  | 
    if (sscanf(yyvsp[0].v.string, "0x%8x%8x%8x%8x",  | 
    ||
3130  | 
    &yyval.v.key.key.data[0], &yyval.v.key.key.data[1],  | 
    ||
3131  | 
    				    &yyval.v.key.key.data[2], &yyval.v.key.key.data[3]) != 4) { | 
    ||
3132  | 
    free(yyvsp[0].v.string);  | 
    ||
3133  | 
    					yyerror("invalid hex key"); | 
    ||
3134  | 
    YYERROR;  | 
    ||
3135  | 
    }  | 
    ||
3136  | 
    			} else { | 
    ||
3137  | 
    MD5_CTX context;  | 
    ||
3138  | 
    |||
3139  | 
    MD5Init(&context);  | 
    ||
3140  | 
    MD5Update(&context, (unsigned char *)yyvsp[0].v.string,  | 
    ||
3141  | 
    strlen(yyvsp[0].v.string));  | 
    ||
3142  | 
    MD5Final((unsigned char *)yyval.v.key.key.data,  | 
    ||
3143  | 
    &context);  | 
    ||
3144  | 
    HTONL(yyval.v.key.key.data[0]);  | 
    ||
3145  | 
    HTONL(yyval.v.key.key.data[1]);  | 
    ||
3146  | 
    HTONL(yyval.v.key.key.data[2]);  | 
    ||
3147  | 
    HTONL(yyval.v.key.key.data[3]);  | 
    ||
3148  | 
    }  | 
    ||
3149  | 
    free(yyvsp[0].v.string);  | 
    ||
3150  | 
    }  | 
    ||
3151  | 
    break;  | 
    ||
3152  | 
    case 86:  | 
    ||
3153  | 
    #line 853 "parse.y"  | 
    ||
3154  | 
    { table->conf.check = CHECK_ICMP; } | 
    ||
3155  | 
    break;  | 
    ||
3156  | 
    case 87:  | 
    ||
3157  | 
    #line 854 "parse.y"  | 
    ||
3158  | 
    { table->conf.check = CHECK_TCP; } | 
    ||
3159  | 
    break;  | 
    ||
3160  | 
    case 88:  | 
    ||
3161  | 
    #line 855 "parse.y"  | 
    ||
3162  | 
    { | 
    ||
3163  | 
    table->conf.check = CHECK_TCP;  | 
    ||
3164  | 
    conf->sc_conf.flags |= F_TLS;  | 
    ||
3165  | 
    table->conf.flags |= F_TLS;  | 
    ||
3166  | 
    }  | 
    ||
3167  | 
    break;  | 
    ||
3168  | 
    case 89:  | 
    ||
3169  | 
    #line 860 "parse.y"  | 
    ||
3170  | 
    { | 
    ||
3171  | 
    			if (yyvsp[-4].v.number) { | 
    ||
3172  | 
    conf->sc_conf.flags |= F_TLS;  | 
    ||
3173  | 
    table->conf.flags |= F_TLS;  | 
    ||
3174  | 
    }  | 
    ||
3175  | 
    table->conf.check = CHECK_HTTP_CODE;  | 
    ||
3176  | 
    			if ((table->conf.retcode = yyvsp[0].v.number) <= 0) { | 
    ||
3177  | 
    				yyerror("invalid HTTP code: %d", yyvsp[0].v.number); | 
    ||
3178  | 
    free(yyvsp[-3].v.string);  | 
    ||
3179  | 
    free(yyvsp[-2].v.string);  | 
    ||
3180  | 
    YYERROR;  | 
    ||
3181  | 
    }  | 
    ||
3182  | 
    if (asprintf(&table->sendbuf,  | 
    ||
3183  | 
    "HEAD %s HTTP/1.%c\r\n%s\r\n",  | 
    ||
3184  | 
    yyvsp[-3].v.string, strlen(yyvsp[-2].v.string) ? '1' : '0', yyvsp[-2].v.string) == -1)  | 
    ||
3185  | 
    				fatal("asprintf"); | 
    ||
3186  | 
    free(yyvsp[-3].v.string);  | 
    ||
3187  | 
    free(yyvsp[-2].v.string);  | 
    ||
3188  | 
    if (table->sendbuf == NULL)  | 
    ||
3189  | 
    				fatal("out of memory"); | 
    ||
3190  | 
    }  | 
    ||
3191  | 
    break;  | 
    ||
3192  | 
    case 90:  | 
    ||
3193  | 
    #line 881 "parse.y"  | 
    ||
3194  | 
    { | 
    ||
3195  | 
    			if (yyvsp[-3].v.number) { | 
    ||
3196  | 
    conf->sc_conf.flags |= F_TLS;  | 
    ||
3197  | 
    table->conf.flags |= F_TLS;  | 
    ||
3198  | 
    }  | 
    ||
3199  | 
    table->conf.check = CHECK_HTTP_DIGEST;  | 
    ||
3200  | 
    if (asprintf(&table->sendbuf,  | 
    ||
3201  | 
    "GET %s HTTP/1.%c\r\n%s\r\n",  | 
    ||
3202  | 
    yyvsp[-2].v.string, strlen(yyvsp[-1].v.string) ? '1' : '0', yyvsp[-1].v.string) == -1)  | 
    ||
3203  | 
    				fatal("asprintf"); | 
    ||
3204  | 
    free(yyvsp[-2].v.string);  | 
    ||
3205  | 
    free(yyvsp[-1].v.string);  | 
    ||
3206  | 
    if (table->sendbuf == NULL)  | 
    ||
3207  | 
    				fatal("out of memory"); | 
    ||
3208  | 
    if (strlcpy(table->conf.digest, yyvsp[0].v.digest.digest,  | 
    ||
3209  | 
    sizeof(table->conf.digest)) >=  | 
    ||
3210  | 
    			    sizeof(table->conf.digest)) { | 
    ||
3211  | 
    				yyerror("digest truncated"); | 
    ||
3212  | 
    free(yyvsp[0].v.digest.digest);  | 
    ||
3213  | 
    YYERROR;  | 
    ||
3214  | 
    }  | 
    ||
3215  | 
    table->conf.digest_type = yyvsp[0].v.digest.type;  | 
    ||
3216  | 
    free(yyvsp[0].v.digest.digest);  | 
    ||
3217  | 
    }  | 
    ||
3218  | 
    break;  | 
    ||
3219  | 
    case 91:  | 
    ||
3220  | 
    #line 905 "parse.y"  | 
    ||
3221  | 
    { | 
    ||
3222  | 
    table->conf.check = CHECK_SEND_EXPECT;  | 
    ||
3223  | 
    			if (yyvsp[0].v.number) { | 
    ||
3224  | 
    conf->sc_conf.flags |= F_TLS;  | 
    ||
3225  | 
    table->conf.flags |= F_TLS;  | 
    ||
3226  | 
    }  | 
    ||
3227  | 
    if (strlcpy(table->conf.exbuf, yyvsp[-1].v.string,  | 
    ||
3228  | 
    sizeof(table->conf.exbuf))  | 
    ||
3229  | 
    			    >= sizeof(table->conf.exbuf)) { | 
    ||
3230  | 
    				yyerror("yyparse: expect buffer truncated"); | 
    ||
3231  | 
    free(yyvsp[-1].v.string);  | 
    ||
3232  | 
    YYERROR;  | 
    ||
3233  | 
    }  | 
    ||
3234  | 
    translate_string(table->conf.exbuf);  | 
    ||
3235  | 
    free(yyvsp[-1].v.string);  | 
    ||
3236  | 
    }  | 
    ||
3237  | 
    break;  | 
    ||
3238  | 
    case 92:  | 
    ||
3239  | 
    #line 921 "parse.y"  | 
    ||
3240  | 
    { | 
    ||
3241  | 
    table->conf.check = CHECK_SCRIPT;  | 
    ||
3242  | 
    if (strlcpy(table->conf.path, yyvsp[0].v.string,  | 
    ||
3243  | 
    sizeof(table->conf.path)) >=  | 
    ||
3244  | 
    			    sizeof(table->conf.path)) { | 
    ||
3245  | 
    				yyerror("script path truncated"); | 
    ||
3246  | 
    free(yyvsp[0].v.string);  | 
    ||
3247  | 
    YYERROR;  | 
    ||
3248  | 
    }  | 
    ||
3249  | 
    conf->sc_conf.flags |= F_SCRIPT;  | 
    ||
3250  | 
    free(yyvsp[0].v.string);  | 
    ||
3251  | 
    }  | 
    ||
3252  | 
    break;  | 
    ||
3253  | 
    case 93:  | 
    ||
3254  | 
    #line 936 "parse.y"  | 
    ||
3255  | 
    { | 
    ||
3256  | 
    			switch (strlen(yyvsp[0].v.string)) { | 
    ||
3257  | 
    case 40:  | 
    ||
3258  | 
    yyval.v.digest.type = DIGEST_SHA1;  | 
    ||
3259  | 
    break;  | 
    ||
3260  | 
    case 32:  | 
    ||
3261  | 
    yyval.v.digest.type = DIGEST_MD5;  | 
    ||
3262  | 
    break;  | 
    ||
3263  | 
    default:  | 
    ||
3264  | 
    				yyerror("invalid http digest"); | 
    ||
3265  | 
    free(yyvsp[0].v.string);  | 
    ||
3266  | 
    YYERROR;  | 
    ||
3267  | 
    }  | 
    ||
3268  | 
    yyval.v.digest.digest = yyvsp[0].v.string;  | 
    ||
3269  | 
    }  | 
    ||
3270  | 
    break;  | 
    ||
3271  | 
    case 94:  | 
    ||
3272  | 
    #line 953 "parse.y"  | 
    ||
3273  | 
    { | 
    ||
3274  | 
    yyval.v.digest.digest = yyvsp[0].v.digest.digest;  | 
    ||
3275  | 
    yyval.v.digest.type = yyvsp[0].v.digest.type;  | 
    ||
3276  | 
    }  | 
    ||
3277  | 
    break;  | 
    ||
3278  | 
    case 95:  | 
    ||
3279  | 
    #line 957 "parse.y"  | 
    ||
3280  | 
    { | 
    ||
3281  | 
    yyval.v.digest.digest = yyvsp[0].v.string;  | 
    ||
3282  | 
    yyval.v.digest.type = DIGEST_NONE;  | 
    ||
3283  | 
    }  | 
    ||
3284  | 
    break;  | 
    ||
3285  | 
    case 96:  | 
    ||
3286  | 
    #line 963 "parse.y"  | 
    ||
3287  | 
    { | 
    ||
3288  | 
    struct protocol *p;  | 
    ||
3289  | 
    |||
3290  | 
    			if (!loadcfg) { | 
    ||
3291  | 
    free(yyvsp[0].v.string);  | 
    ||
3292  | 
    YYACCEPT;  | 
    ||
3293  | 
    }  | 
    ||
3294  | 
    |||
3295  | 
    			if (strcmp(yyvsp[0].v.string, "default") == 0) { | 
    ||
3296  | 
    p = &conf->sc_proto_default;  | 
    ||
3297  | 
    			} else { | 
    ||
3298  | 
    TAILQ_FOREACH(p, conf->sc_protos, entry)  | 
    ||
3299  | 
    if (!strcmp(p->name, yyvsp[0].v.string))  | 
    ||
3300  | 
    break;  | 
    ||
3301  | 
    }  | 
    ||
3302  | 
    			if (p != NULL) { | 
    ||
3303  | 
    				yyerror("protocol %s defined twice", yyvsp[0].v.string); | 
    ||
3304  | 
    free(yyvsp[0].v.string);  | 
    ||
3305  | 
    YYERROR;  | 
    ||
3306  | 
    }  | 
    ||
3307  | 
    if ((p = calloc(1, sizeof (*p))) == NULL)  | 
    ||
3308  | 
    				fatal("out of memory"); | 
    ||
3309  | 
    |||
3310  | 
    if (strlcpy(p->name, yyvsp[0].v.string, sizeof(p->name)) >=  | 
    ||
3311  | 
    			    sizeof(p->name)) { | 
    ||
3312  | 
    				yyerror("protocol name truncated"); | 
    ||
3313  | 
    free(yyvsp[0].v.string);  | 
    ||
3314  | 
    free(p);  | 
    ||
3315  | 
    YYERROR;  | 
    ||
3316  | 
    }  | 
    ||
3317  | 
    free(yyvsp[0].v.string);  | 
    ||
3318  | 
    p->id = ++last_proto_id;  | 
    ||
3319  | 
    p->type = yyvsp[-2].v.number;  | 
    ||
3320  | 
    p->tcpflags = TCPFLAG_DEFAULT;  | 
    ||
3321  | 
    p->tlsflags = TLSFLAG_DEFAULT;  | 
    ||
3322  | 
    p->tcpbacklog = RELAY_BACKLOG;  | 
    ||
3323  | 
    TAILQ_INIT(&p->rules);  | 
    ||
3324  | 
    (void)strlcpy(p->tlsciphers, TLSCIPHERS_DEFAULT,  | 
    ||
3325  | 
    sizeof(p->tlsciphers));  | 
    ||
3326  | 
    (void)strlcpy(p->tlsecdhcurve, TLSECDHCURVE_DEFAULT,  | 
    ||
3327  | 
    sizeof(p->tlsecdhcurve));  | 
    ||
3328  | 
    (void)strlcpy(p->tlsdhparams, TLSDHPARAM_DEFAULT,  | 
    ||
3329  | 
    sizeof(p->tlsdhparams));  | 
    ||
3330  | 
    			if (last_proto_id == INT_MAX) { | 
    ||
3331  | 
    				yyerror("too many protocols defined"); | 
    ||
3332  | 
    free(p);  | 
    ||
3333  | 
    YYERROR;  | 
    ||
3334  | 
    }  | 
    ||
3335  | 
    proto = p;  | 
    ||
3336  | 
    }  | 
    ||
3337  | 
    break;  | 
    ||
3338  | 
    case 97:  | 
    ||
3339  | 
    #line 1012 "parse.y"  | 
    ||
3340  | 
    { | 
    ||
3341  | 
    conf->sc_protocount++;  | 
    ||
3342  | 
    |||
3343  | 
    			if ((proto->tlsflags & TLSFLAG_VERSION) == 0) { | 
    ||
3344  | 
    				yyerror("invalid TLS protocol"); | 
    ||
3345  | 
    YYERROR;  | 
    ||
3346  | 
    }  | 
    ||
3347  | 
    |||
3348  | 
    TAILQ_INSERT_TAIL(conf->sc_protos, proto, entry);  | 
    ||
3349  | 
    }  | 
    ||
3350  | 
    break;  | 
    ||
3351  | 
    case 107:  | 
    ||
3352  | 
    #line 1037 "parse.y"  | 
    ||
3353  | 
    { proto->flags |= F_RETURN; } | 
    ||
3354  | 
    break;  | 
    ||
3355  | 
    case 108:  | 
    ||
3356  | 
    #line 1038 "parse.y"  | 
    ||
3357  | 
    { proto->flags |= F_RETURN; } | 
    ||
3358  | 
    break;  | 
    ||
3359  | 
    case 113:  | 
    ||
3360  | 
    #line 1047 "parse.y"  | 
    ||
3361  | 
    { proto->tcpflags |= TCPFLAG_SACK; } | 
    ||
3362  | 
    break;  | 
    ||
3363  | 
    case 114:  | 
    ||
3364  | 
    #line 1048 "parse.y"  | 
    ||
3365  | 
    { proto->tcpflags |= TCPFLAG_NSACK; } | 
    ||
3366  | 
    break;  | 
    ||
3367  | 
    case 115:  | 
    ||
3368  | 
    #line 1049 "parse.y"  | 
    ||
3369  | 
    { proto->tcpflags |= TCPFLAG_NODELAY; } | 
    ||
3370  | 
    break;  | 
    ||
3371  | 
    case 116:  | 
    ||
3372  | 
    #line 1050 "parse.y"  | 
    ||
3373  | 
    { proto->tcpflags |= TCPFLAG_NNODELAY; } | 
    ||
3374  | 
    break;  | 
    ||
3375  | 
    case 117:  | 
    ||
3376  | 
    #line 1051 "parse.y"  | 
    ||
3377  | 
    { /* default */ } | 
    ||
3378  | 
    break;  | 
    ||
3379  | 
    case 118:  | 
    ||
3380  | 
    #line 1052 "parse.y"  | 
    ||
3381  | 
    { proto->tcpflags |= TCPFLAG_NSPLICE; } | 
    ||
3382  | 
    break;  | 
    ||
3383  | 
    case 119:  | 
    ||
3384  | 
    #line 1053 "parse.y"  | 
    ||
3385  | 
    { | 
    ||
3386  | 
    			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RELAY_MAX_SESSIONS) { | 
    ||
3387  | 
    				yyerror("invalid backlog: %d", yyvsp[0].v.number); | 
    ||
3388  | 
    YYERROR;  | 
    ||
3389  | 
    }  | 
    ||
3390  | 
    proto->tcpbacklog = yyvsp[0].v.number;  | 
    ||
3391  | 
    }  | 
    ||
3392  | 
    break;  | 
    ||
3393  | 
    case 120:  | 
    ||
3394  | 
    #line 1060 "parse.y"  | 
    ||
3395  | 
    { | 
    ||
3396  | 
    proto->tcpflags |= TCPFLAG_BUFSIZ;  | 
    ||
3397  | 
    			if ((proto->tcpbufsiz = yyvsp[0].v.number) < 0) { | 
    ||
3398  | 
    				yyerror("invalid socket buffer size: %d", yyvsp[0].v.number); | 
    ||
3399  | 
    YYERROR;  | 
    ||
3400  | 
    }  | 
    ||
3401  | 
    }  | 
    ||
3402  | 
    break;  | 
    ||
3403  | 
    case 121:  | 
    ||
3404  | 
    #line 1067 "parse.y"  | 
    ||
3405  | 
    { | 
    ||
3406  | 
    			if (yyvsp[0].v.number < 0) { | 
    ||
3407  | 
    				yyerror("invalid ttl: %d", yyvsp[0].v.number); | 
    ||
3408  | 
    free(yyvsp[-1].v.string);  | 
    ||
3409  | 
    YYERROR;  | 
    ||
3410  | 
    }  | 
    ||
3411  | 
    			if (strcasecmp("ttl", yyvsp[-1].v.string) == 0) { | 
    ||
3412  | 
    proto->tcpflags |= TCPFLAG_IPTTL;  | 
    ||
3413  | 
    proto->tcpipttl = yyvsp[0].v.number;  | 
    ||
3414  | 
    			} else if (strcasecmp("minttl", yyvsp[-1].v.string) == 0) { | 
    ||
3415  | 
    proto->tcpflags |= TCPFLAG_IPMINTTL;  | 
    ||
3416  | 
    proto->tcpipminttl = yyvsp[0].v.number;  | 
    ||
3417  | 
    			} else { | 
    ||
3418  | 
    				yyerror("invalid TCP/IP flag: %s", yyvsp[-1].v.string); | 
    ||
3419  | 
    free(yyvsp[-1].v.string);  | 
    ||
3420  | 
    YYERROR;  | 
    ||
3421  | 
    }  | 
    ||
3422  | 
    free(yyvsp[-1].v.string);  | 
    ||
3423  | 
    }  | 
    ||
3424  | 
    break;  | 
    ||
3425  | 
    case 124:  | 
    ||
3426  | 
    #line 1092 "parse.y"  | 
    ||
3427  | 
    { proto->tickets = 1; } | 
    ||
3428  | 
    break;  | 
    ||
3429  | 
    case 125:  | 
    ||
3430  | 
    #line 1093 "parse.y"  | 
    ||
3431  | 
    { proto->tickets = 0; } | 
    ||
3432  | 
    break;  | 
    ||
3433  | 
    case 126:  | 
    ||
3434  | 
    #line 1094 "parse.y"  | 
    ||
3435  | 
    { | 
    ||
3436  | 
    if (strlcpy(proto->tlsciphers, yyvsp[0].v.string,  | 
    ||
3437  | 
    sizeof(proto->tlsciphers)) >=  | 
    ||
3438  | 
    			    sizeof(proto->tlsciphers)) { | 
    ||
3439  | 
    				yyerror("tlsciphers truncated"); | 
    ||
3440  | 
    free(yyvsp[0].v.string);  | 
    ||
3441  | 
    YYERROR;  | 
    ||
3442  | 
    }  | 
    ||
3443  | 
    free(yyvsp[0].v.string);  | 
    ||
3444  | 
    }  | 
    ||
3445  | 
    break;  | 
    ||
3446  | 
    case 127:  | 
    ||
3447  | 
    #line 1104 "parse.y"  | 
    ||
3448  | 
    { | 
    ||
3449  | 
    (void)strlcpy(proto->tlsdhparams, "none",  | 
    ||
3450  | 
    sizeof(proto->tlsdhparams));  | 
    ||
3451  | 
    }  | 
    ||
3452  | 
    break;  | 
    ||
3453  | 
    case 128:  | 
    ||
3454  | 
    #line 1108 "parse.y"  | 
    ||
3455  | 
    { | 
    ||
3456  | 
    (void)strlcpy(proto->tlsdhparams, "auto",  | 
    ||
3457  | 
    sizeof(proto->tlsdhparams));  | 
    ||
3458  | 
    }  | 
    ||
3459  | 
    break;  | 
    ||
3460  | 
    case 129:  | 
    ||
3461  | 
    #line 1112 "parse.y"  | 
    ||
3462  | 
    { | 
    ||
3463  | 
    struct tls_config *tls_cfg;  | 
    ||
3464  | 
    			if ((tls_cfg = tls_config_new()) == NULL) { | 
    ||
3465  | 
    				yyerror("tls_config_new failed"); | 
    ||
3466  | 
    free(yyvsp[0].v.string);  | 
    ||
3467  | 
    YYERROR;  | 
    ||
3468  | 
    }  | 
    ||
3469  | 
    			if (tls_config_set_dheparams(tls_cfg, yyvsp[0].v.string) != 0) { | 
    ||
3470  | 
    				yyerror("tls edh params %s: %s", yyvsp[0].v.string, | 
    ||
3471  | 
    tls_config_error(tls_cfg));  | 
    ||
3472  | 
    tls_config_free(tls_cfg);  | 
    ||
3473  | 
    free(yyvsp[0].v.string);  | 
    ||
3474  | 
    YYERROR;  | 
    ||
3475  | 
    }  | 
    ||
3476  | 
    tls_config_free(tls_cfg);  | 
    ||
3477  | 
    if (strlcpy(proto->tlsdhparams, yyvsp[0].v.string,  | 
    ||
3478  | 
    sizeof(proto->tlsdhparams)) >=  | 
    ||
3479  | 
    			    sizeof(proto->tlsdhparams)) { | 
    ||
3480  | 
    				yyerror("tls edh truncated"); | 
    ||
3481  | 
    free(yyvsp[0].v.string);  | 
    ||
3482  | 
    YYERROR;  | 
    ||
3483  | 
    }  | 
    ||
3484  | 
    free(yyvsp[0].v.string);  | 
    ||
3485  | 
    }  | 
    ||
3486  | 
    break;  | 
    ||
3487  | 
    case 130:  | 
    ||
3488  | 
    #line 1136 "parse.y"  | 
    ||
3489  | 
    { | 
    ||
3490  | 
    (void)strlcpy(proto->tlsecdhcurve, "none",  | 
    ||
3491  | 
    sizeof(proto->tlsecdhcurve));  | 
    ||
3492  | 
    }  | 
    ||
3493  | 
    break;  | 
    ||
3494  | 
    case 131:  | 
    ||
3495  | 
    #line 1140 "parse.y"  | 
    ||
3496  | 
    { | 
    ||
3497  | 
    (void)strlcpy(proto->tlsecdhcurve, "auto",  | 
    ||
3498  | 
    sizeof(proto->tlsecdhcurve));  | 
    ||
3499  | 
    }  | 
    ||
3500  | 
    break;  | 
    ||
3501  | 
    case 132:  | 
    ||
3502  | 
    #line 1144 "parse.y"  | 
    ||
3503  | 
    { | 
    ||
3504  | 
    struct tls_config *tls_cfg;  | 
    ||
3505  | 
    			if ((tls_cfg = tls_config_new()) == NULL) { | 
    ||
3506  | 
    				yyerror("tls_config_new failed"); | 
    ||
3507  | 
    free(yyvsp[0].v.string);  | 
    ||
3508  | 
    YYERROR;  | 
    ||
3509  | 
    }  | 
    ||
3510  | 
    			if (tls_config_set_ecdhecurve(tls_cfg, yyvsp[0].v.string) != 0) { | 
    ||
3511  | 
    				yyerror("tls ecdh curve %s: %s", yyvsp[0].v.string, | 
    ||
3512  | 
    tls_config_error(tls_cfg));  | 
    ||
3513  | 
    tls_config_free(tls_cfg);  | 
    ||
3514  | 
    free(yyvsp[0].v.string);  | 
    ||
3515  | 
    YYERROR;  | 
    ||
3516  | 
    }  | 
    ||
3517  | 
    tls_config_free(tls_cfg);  | 
    ||
3518  | 
    if (strlcpy(proto->tlsecdhcurve, yyvsp[0].v.string,  | 
    ||
3519  | 
    sizeof(proto->tlsecdhcurve)) >=  | 
    ||
3520  | 
    			    sizeof(proto->tlsecdhcurve)) { | 
    ||
3521  | 
    				yyerror("tls ecdh truncated"); | 
    ||
3522  | 
    free(yyvsp[0].v.string);  | 
    ||
3523  | 
    YYERROR;  | 
    ||
3524  | 
    }  | 
    ||
3525  | 
    free(yyvsp[0].v.string);  | 
    ||
3526  | 
    }  | 
    ||
3527  | 
    break;  | 
    ||
3528  | 
    case 133:  | 
    ||
3529  | 
    #line 1168 "parse.y"  | 
    ||
3530  | 
    { | 
    ||
3531  | 
    if (strlcpy(proto->tlsca, yyvsp[0].v.string,  | 
    ||
3532  | 
    sizeof(proto->tlsca)) >=  | 
    ||
3533  | 
    			    sizeof(proto->tlsca)) { | 
    ||
3534  | 
    				yyerror("tlsca truncated"); | 
    ||
3535  | 
    free(yyvsp[0].v.string);  | 
    ||
3536  | 
    YYERROR;  | 
    ||
3537  | 
    }  | 
    ||
3538  | 
    free(yyvsp[0].v.string);  | 
    ||
3539  | 
    }  | 
    ||
3540  | 
    break;  | 
    ||
3541  | 
    case 134:  | 
    ||
3542  | 
    #line 1178 "parse.y"  | 
    ||
3543  | 
    { | 
    ||
3544  | 
    if (strlcpy(proto->tlscakey, yyvsp[-2].v.string,  | 
    ||
3545  | 
    sizeof(proto->tlscakey)) >=  | 
    ||
3546  | 
    			    sizeof(proto->tlscakey)) { | 
    ||
3547  | 
    				yyerror("tlscakey truncated"); | 
    ||
3548  | 
    free(yyvsp[-2].v.string);  | 
    ||
3549  | 
    free(yyvsp[0].v.string);  | 
    ||
3550  | 
    YYERROR;  | 
    ||
3551  | 
    }  | 
    ||
3552  | 
    			if ((proto->tlscapass = strdup(yyvsp[0].v.string)) == NULL) { | 
    ||
3553  | 
    				yyerror("tlscapass"); | 
    ||
3554  | 
    free(yyvsp[-2].v.string);  | 
    ||
3555  | 
    free(yyvsp[0].v.string);  | 
    ||
3556  | 
    YYERROR;  | 
    ||
3557  | 
    }  | 
    ||
3558  | 
    free(yyvsp[-2].v.string);  | 
    ||
3559  | 
    free(yyvsp[0].v.string);  | 
    ||
3560  | 
    }  | 
    ||
3561  | 
    break;  | 
    ||
3562  | 
    case 135:  | 
    ||
3563  | 
    #line 1196 "parse.y"  | 
    ||
3564  | 
    { | 
    ||
3565  | 
    if (strlcpy(proto->tlscacert, yyvsp[0].v.string,  | 
    ||
3566  | 
    sizeof(proto->tlscacert)) >=  | 
    ||
3567  | 
    			    sizeof(proto->tlscacert)) { | 
    ||
3568  | 
    				yyerror("tlscacert truncated"); | 
    ||
3569  | 
    free(yyvsp[0].v.string);  | 
    ||
3570  | 
    YYERROR;  | 
    ||
3571  | 
    }  | 
    ||
3572  | 
    free(yyvsp[0].v.string);  | 
    ||
3573  | 
    }  | 
    ||
3574  | 
    break;  | 
    ||
3575  | 
    case 136:  | 
    ||
3576  | 
    #line 1206 "parse.y"  | 
    ||
3577  | 
    { proto->tlsflags &= ~(yyvsp[0].v.number); } | 
    ||
3578  | 
    break;  | 
    ||
3579  | 
    case 137:  | 
    ||
3580  | 
    #line 1207 "parse.y"  | 
    ||
3581  | 
    { proto->tlsflags |= yyvsp[0].v.number; } | 
    ||
3582  | 
    break;  | 
    ||
3583  | 
    case 138:  | 
    ||
3584  | 
    #line 1210 "parse.y"  | 
    ||
3585  | 
    { | 
    ||
3586  | 
    			if (strcmp("sslv3", yyvsp[0].v.string) == 0) | 
    ||
3587  | 
    yyval.v.number = TLSFLAG_SSLV3;  | 
    ||
3588  | 
    			else if (strcmp("tlsv1", yyvsp[0].v.string) == 0) | 
    ||
3589  | 
    yyval.v.number = TLSFLAG_TLSV1;  | 
    ||
3590  | 
    			else if (strcmp("tlsv1.0", yyvsp[0].v.string) == 0) | 
    ||
3591  | 
    yyval.v.number = TLSFLAG_TLSV1_0;  | 
    ||
3592  | 
    			else if (strcmp("tlsv1.1", yyvsp[0].v.string) == 0) | 
    ||
3593  | 
    yyval.v.number = TLSFLAG_TLSV1_1;  | 
    ||
3594  | 
    			else if (strcmp("tlsv1.2", yyvsp[0].v.string) == 0) | 
    ||
3595  | 
    yyval.v.number = TLSFLAG_TLSV1_2;  | 
    ||
3596  | 
    			else if (strcmp("cipher-server-preference", yyvsp[0].v.string) == 0) | 
    ||
3597  | 
    yyval.v.number = TLSFLAG_CIPHER_SERVER_PREF;  | 
    ||
3598  | 
    			else if (strcmp("client-renegotiation", yyvsp[0].v.string) == 0) | 
    ||
3599  | 
    yyval.v.number = TLSFLAG_CLIENT_RENEG;  | 
    ||
3600  | 
    			else { | 
    ||
3601  | 
    				yyerror("invalid TLS flag: %s", yyvsp[0].v.string); | 
    ||
3602  | 
    free(yyvsp[0].v.string);  | 
    ||
3603  | 
    YYERROR;  | 
    ||
3604  | 
    }  | 
    ||
3605  | 
    free(yyvsp[0].v.string);  | 
    ||
3606  | 
    }  | 
    ||
3607  | 
    break;  | 
    ||
3608  | 
    case 139:  | 
    ||
3609  | 
    #line 1234 "parse.y"  | 
    ||
3610  | 
    { | 
    ||
3611  | 
    if ((rule = calloc(1, sizeof(*rule))) == NULL)  | 
    ||
3612  | 
    				fatal("out of memory"); | 
    ||
3613  | 
    |||
3614  | 
    rule->rule_action = yyvsp[-5].v.number;  | 
    ||
3615  | 
    rule->rule_proto = proto->type;  | 
    ||
3616  | 
    rule->rule_dir = yyvsp[-4].v.dir;  | 
    ||
3617  | 
    rule->rule_flags |= yyvsp[-3].v.number;  | 
    ||
3618  | 
    rule->rule_af = yyvsp[-2].v.number;  | 
    ||
3619  | 
    |||
3620  | 
    rulefile = NULL;  | 
    ||
3621  | 
    }  | 
    ||
3622  | 
    break;  | 
    ||
3623  | 
    case 140:  | 
    ||
3624  | 
    #line 1245 "parse.y"  | 
    ||
3625  | 
    { | 
    ||
3626  | 
    			if (rule_add(proto, rule, rulefile) == -1) { | 
    ||
3627  | 
    				if (rulefile == NULL) { | 
    ||
3628  | 
    					yyerror("failed to load rule"); | 
    ||
3629  | 
    				} else { | 
    ||
3630  | 
    					yyerror("failed to load rules from %s", | 
    ||
3631  | 
    rulefile);  | 
    ||
3632  | 
    free(rulefile);  | 
    ||
3633  | 
    }  | 
    ||
3634  | 
    rule_free(rule);  | 
    ||
3635  | 
    free(rule);  | 
    ||
3636  | 
    YYERROR;  | 
    ||
3637  | 
    }  | 
    ||
3638  | 
    if (rulefile)  | 
    ||
3639  | 
    free(rulefile);  | 
    ||
3640  | 
    rulefile = NULL;  | 
    ||
3641  | 
    rule = NULL;  | 
    ||
3642  | 
    keytype = KEY_TYPE_NONE;  | 
    ||
3643  | 
    }  | 
    ||
3644  | 
    break;  | 
    ||
3645  | 
    case 141:  | 
    ||
3646  | 
    #line 1266 "parse.y"  | 
    ||
3647  | 
    { yyval.v.number = RULE_ACTION_PASS; } | 
    ||
3648  | 
    break;  | 
    ||
3649  | 
    case 142:  | 
    ||
3650  | 
    #line 1267 "parse.y"  | 
    ||
3651  | 
    { yyval.v.number = RULE_ACTION_BLOCK; } | 
    ||
3652  | 
    break;  | 
    ||
3653  | 
    case 143:  | 
    ||
3654  | 
    #line 1268 "parse.y"  | 
    ||
3655  | 
    { yyval.v.number = RULE_ACTION_MATCH; } | 
    ||
3656  | 
    break;  | 
    ||
3657  | 
    case 144:  | 
    ||
3658  | 
    #line 1271 "parse.y"  | 
    ||
3659  | 
    { | 
    ||
3660  | 
    yyval.v.dir = dir = RELAY_DIR_REQUEST;  | 
    ||
3661  | 
    }  | 
    ||
3662  | 
    break;  | 
    ||
3663  | 
    case 145:  | 
    ||
3664  | 
    #line 1274 "parse.y"  | 
    ||
3665  | 
    { | 
    ||
3666  | 
    yyval.v.dir = dir = RELAY_DIR_REQUEST;  | 
    ||
3667  | 
    }  | 
    ||
3668  | 
    break;  | 
    ||
3669  | 
    case 146:  | 
    ||
3670  | 
    #line 1277 "parse.y"  | 
    ||
3671  | 
    { | 
    ||
3672  | 
    yyval.v.dir = dir = RELAY_DIR_RESPONSE;  | 
    ||
3673  | 
    }  | 
    ||
3674  | 
    break;  | 
    ||
3675  | 
    case 147:  | 
    ||
3676  | 
    #line 1282 "parse.y"  | 
    ||
3677  | 
    { yyval.v.number = 0; } | 
    ||
3678  | 
    break;  | 
    ||
3679  | 
    case 148:  | 
    ||
3680  | 
    #line 1283 "parse.y"  | 
    ||
3681  | 
    { yyval.v.number = RULE_FLAG_QUICK; } | 
    ||
3682  | 
    break;  | 
    ||
3683  | 
    case 149:  | 
    ||
3684  | 
    #line 1286 "parse.y"  | 
    ||
3685  | 
    { yyval.v.number = AF_UNSPEC; } | 
    ||
3686  | 
    break;  | 
    ||
3687  | 
    case 150:  | 
    ||
3688  | 
    #line 1287 "parse.y"  | 
    ||
3689  | 
    { yyval.v.number = AF_INET6; } | 
    ||
3690  | 
    break;  | 
    ||
3691  | 
    case 151:  | 
    ||
3692  | 
    #line 1288 "parse.y"  | 
    ||
3693  | 
    { yyval.v.number = AF_INET; } | 
    ||
3694  | 
    break;  | 
    ||
3695  | 
    case 158:  | 
    ||
3696  | 
    #line 1305 "parse.y"  | 
    ||
3697  | 
    { | 
    ||
3698  | 
    u_int id;  | 
    ||
3699  | 
    if ((id = relay_httpmethod_byname(yyvsp[0].v.string)) ==  | 
    ||
3700  | 
    			    HTTP_METHOD_NONE) { | 
    ||
3701  | 
    				yyerror("unknown HTTP method currently not " | 
    ||
3702  | 
    "supported");  | 
    ||
3703  | 
    free(yyvsp[0].v.string);  | 
    ||
3704  | 
    YYERROR;  | 
    ||
3705  | 
    }  | 
    ||
3706  | 
    rule->rule_method = id;  | 
    ||
3707  | 
    free(yyvsp[0].v.string);  | 
    ||
3708  | 
    }  | 
    ||
3709  | 
    break;  | 
    ||
3710  | 
    case 159:  | 
    ||
3711  | 
    #line 1317 "parse.y"  | 
    ||
3712  | 
    { | 
    ||
3713  | 
    keytype = KEY_TYPE_COOKIE;  | 
    ||
3714  | 
    rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);  | 
    ||
3715  | 
    rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;  | 
    ||
3716  | 
    rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?  | 
    ||
3717  | 
    			    strdup(yyvsp[0].v.string) : strdup("*")); | 
    ||
3718  | 
    if (rule->rule_kv[keytype].kv_key == NULL ||  | 
    ||
3719  | 
    rule->rule_kv[keytype].kv_value == NULL)  | 
    ||
3720  | 
    				fatal("out of memory"); | 
    ||
3721  | 
    free(yyvsp[-1].v.string);  | 
    ||
3722  | 
    if (yyvsp[0].v.string)  | 
    ||
3723  | 
    free(yyvsp[0].v.string);  | 
    ||
3724  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3725  | 
    }  | 
    ||
3726  | 
    break;  | 
    ||
3727  | 
    case 160:  | 
    ||
3728  | 
    #line 1331 "parse.y"  | 
    ||
3729  | 
    { | 
    ||
3730  | 
    keytype = KEY_TYPE_COOKIE;  | 
    ||
3731  | 
    rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;  | 
    ||
3732  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3733  | 
    }  | 
    ||
3734  | 
    break;  | 
    ||
3735  | 
    case 161:  | 
    ||
3736  | 
    #line 1336 "parse.y"  | 
    ||
3737  | 
    { | 
    ||
3738  | 
    keytype = KEY_TYPE_HEADER;  | 
    ||
3739  | 
    memset(&rule->rule_kv[keytype], 0,  | 
    ||
3740  | 
    sizeof(rule->rule_kv[keytype]));  | 
    ||
3741  | 
    rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;  | 
    ||
3742  | 
    rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);  | 
    ||
3743  | 
    rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?  | 
    ||
3744  | 
    			    strdup(yyvsp[0].v.string) : strdup("*")); | 
    ||
3745  | 
    if (rule->rule_kv[keytype].kv_key == NULL ||  | 
    ||
3746  | 
    rule->rule_kv[keytype].kv_value == NULL)  | 
    ||
3747  | 
    				fatal("out of memory"); | 
    ||
3748  | 
    free(yyvsp[-1].v.string);  | 
    ||
3749  | 
    if (yyvsp[0].v.string)  | 
    ||
3750  | 
    free(yyvsp[0].v.string);  | 
    ||
3751  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3752  | 
    }  | 
    ||
3753  | 
    break;  | 
    ||
3754  | 
    case 162:  | 
    ||
3755  | 
    #line 1352 "parse.y"  | 
    ||
3756  | 
    { | 
    ||
3757  | 
    keytype = KEY_TYPE_HEADER;  | 
    ||
3758  | 
    rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;  | 
    ||
3759  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3760  | 
    }  | 
    ||
3761  | 
    break;  | 
    ||
3762  | 
    case 163:  | 
    ||
3763  | 
    #line 1357 "parse.y"  | 
    ||
3764  | 
    { | 
    ||
3765  | 
    keytype = KEY_TYPE_PATH;  | 
    ||
3766  | 
    rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;  | 
    ||
3767  | 
    rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);  | 
    ||
3768  | 
    rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?  | 
    ||
3769  | 
    			    strdup(yyvsp[0].v.string) : strdup("*")); | 
    ||
3770  | 
    if (rule->rule_kv[keytype].kv_key == NULL ||  | 
    ||
3771  | 
    rule->rule_kv[keytype].kv_value == NULL)  | 
    ||
3772  | 
    				fatal("out of memory"); | 
    ||
3773  | 
    free(yyvsp[-1].v.string);  | 
    ||
3774  | 
    if (yyvsp[0].v.string)  | 
    ||
3775  | 
    free(yyvsp[0].v.string);  | 
    ||
3776  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3777  | 
    }  | 
    ||
3778  | 
    break;  | 
    ||
3779  | 
    case 164:  | 
    ||
3780  | 
    #line 1371 "parse.y"  | 
    ||
3781  | 
    { | 
    ||
3782  | 
    keytype = KEY_TYPE_PATH;  | 
    ||
3783  | 
    rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;  | 
    ||
3784  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3785  | 
    }  | 
    ||
3786  | 
    break;  | 
    ||
3787  | 
    case 165:  | 
    ||
3788  | 
    #line 1376 "parse.y"  | 
    ||
3789  | 
    { | 
    ||
3790  | 
    			switch (yyvsp[-2].v.number) { | 
    ||
3791  | 
    case KEY_OPTION_APPEND:  | 
    ||
3792  | 
    case KEY_OPTION_SET:  | 
    ||
3793  | 
    case KEY_OPTION_REMOVE:  | 
    ||
3794  | 
    				yyerror("combining query type and the given " | 
    ||
3795  | 
    "option is not supported");  | 
    ||
3796  | 
    free(yyvsp[-1].v.string);  | 
    ||
3797  | 
    if (yyvsp[0].v.string)  | 
    ||
3798  | 
    free(yyvsp[0].v.string);  | 
    ||
3799  | 
    YYERROR;  | 
    ||
3800  | 
    break;  | 
    ||
3801  | 
    }  | 
    ||
3802  | 
    keytype = KEY_TYPE_QUERY;  | 
    ||
3803  | 
    rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;  | 
    ||
3804  | 
    rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.string);  | 
    ||
3805  | 
    rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?  | 
    ||
3806  | 
    			    strdup(yyvsp[0].v.string) : strdup("*")); | 
    ||
3807  | 
    if (rule->rule_kv[keytype].kv_key == NULL ||  | 
    ||
3808  | 
    rule->rule_kv[keytype].kv_value == NULL)  | 
    ||
3809  | 
    				fatal("out of memory"); | 
    ||
3810  | 
    free(yyvsp[-1].v.string);  | 
    ||
3811  | 
    if (yyvsp[0].v.string)  | 
    ||
3812  | 
    free(yyvsp[0].v.string);  | 
    ||
3813  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3814  | 
    }  | 
    ||
3815  | 
    break;  | 
    ||
3816  | 
    case 166:  | 
    ||
3817  | 
    #line 1402 "parse.y"  | 
    ||
3818  | 
    { | 
    ||
3819  | 
    			switch (yyvsp[0].v.number) { | 
    ||
3820  | 
    case KEY_OPTION_APPEND:  | 
    ||
3821  | 
    case KEY_OPTION_SET:  | 
    ||
3822  | 
    case KEY_OPTION_REMOVE:  | 
    ||
3823  | 
    				yyerror("combining query type and the given " | 
    ||
3824  | 
    "option is not supported");  | 
    ||
3825  | 
    YYERROR;  | 
    ||
3826  | 
    break;  | 
    ||
3827  | 
    }  | 
    ||
3828  | 
    keytype = KEY_TYPE_QUERY;  | 
    ||
3829  | 
    rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;  | 
    ||
3830  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3831  | 
    }  | 
    ||
3832  | 
    break;  | 
    ||
3833  | 
    case 167:  | 
    ||
3834  | 
    #line 1416 "parse.y"  | 
    ||
3835  | 
    { | 
    ||
3836  | 
    			switch (yyvsp[-2].v.number) { | 
    ||
3837  | 
    case KEY_OPTION_APPEND:  | 
    ||
3838  | 
    case KEY_OPTION_SET:  | 
    ||
3839  | 
    case KEY_OPTION_REMOVE:  | 
    ||
3840  | 
    				yyerror("combining url type and the given " | 
    ||
3841  | 
    "option is not supported");  | 
    ||
3842  | 
    free(yyvsp[-1].v.digest.digest);  | 
    ||
3843  | 
    free(yyvsp[0].v.string);  | 
    ||
3844  | 
    YYERROR;  | 
    ||
3845  | 
    break;  | 
    ||
3846  | 
    }  | 
    ||
3847  | 
    keytype = KEY_TYPE_URL;  | 
    ||
3848  | 
    rule->rule_kv[keytype].kv_option = yyvsp[-2].v.number;  | 
    ||
3849  | 
    rule->rule_kv[keytype].kv_key = strdup(yyvsp[-1].v.digest.digest);  | 
    ||
3850  | 
    rule->rule_kv[keytype].kv_digest = yyvsp[-1].v.digest.type;  | 
    ||
3851  | 
    rule->rule_kv[keytype].kv_value = ((yyvsp[0].v.string != NULL) ?  | 
    ||
3852  | 
    			    strdup(yyvsp[0].v.string) : strdup("*")); | 
    ||
3853  | 
    if (rule->rule_kv[keytype].kv_key == NULL ||  | 
    ||
3854  | 
    rule->rule_kv[keytype].kv_value == NULL)  | 
    ||
3855  | 
    				fatal("out of memory"); | 
    ||
3856  | 
    free(yyvsp[-1].v.digest.digest);  | 
    ||
3857  | 
    if (yyvsp[0].v.string)  | 
    ||
3858  | 
    free(yyvsp[0].v.string);  | 
    ||
3859  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3860  | 
    }  | 
    ||
3861  | 
    break;  | 
    ||
3862  | 
    case 168:  | 
    ||
3863  | 
    #line 1442 "parse.y"  | 
    ||
3864  | 
    { | 
    ||
3865  | 
    			switch (yyvsp[0].v.number) { | 
    ||
3866  | 
    case KEY_OPTION_APPEND:  | 
    ||
3867  | 
    case KEY_OPTION_SET:  | 
    ||
3868  | 
    case KEY_OPTION_REMOVE:  | 
    ||
3869  | 
    				yyerror("combining url type and the given " | 
    ||
3870  | 
    "option is not supported");  | 
    ||
3871  | 
    YYERROR;  | 
    ||
3872  | 
    break;  | 
    ||
3873  | 
    }  | 
    ||
3874  | 
    keytype = KEY_TYPE_URL;  | 
    ||
3875  | 
    rule->rule_kv[keytype].kv_option = yyvsp[0].v.number;  | 
    ||
3876  | 
    rule->rule_kv[keytype].kv_type = keytype;  | 
    ||
3877  | 
    }  | 
    ||
3878  | 
    break;  | 
    ||
3879  | 
    case 169:  | 
    ||
3880  | 
    #line 1456 "parse.y"  | 
    ||
3881  | 
    { | 
    ||
3882  | 
    			if (table_findbyname(conf, yyvsp[0].v.string) == NULL) { | 
    ||
3883  | 
    				yyerror("undefined forward table"); | 
    ||
3884  | 
    free(yyvsp[0].v.string);  | 
    ||
3885  | 
    YYERROR;  | 
    ||
3886  | 
    }  | 
    ||
3887  | 
    if (strlcpy(rule->rule_tablename, yyvsp[0].v.string,  | 
    ||
3888  | 
    sizeof(rule->rule_tablename)) >=  | 
    ||
3889  | 
    			    sizeof(rule->rule_tablename)) { | 
    ||
3890  | 
    				yyerror("invalid forward table name"); | 
    ||
3891  | 
    free(yyvsp[0].v.string);  | 
    ||
3892  | 
    YYERROR;  | 
    ||
3893  | 
    }  | 
    ||
3894  | 
    free(yyvsp[0].v.string);  | 
    ||
3895  | 
    }  | 
    ||
3896  | 
    break;  | 
    ||
3897  | 
    case 170:  | 
    ||
3898  | 
    #line 1471 "parse.y"  | 
    ||
3899  | 
    { | 
    ||
3900  | 
    tag = tag_name2id(yyvsp[0].v.string);  | 
    ||
3901  | 
    			if (rule->rule_tag) { | 
    ||
3902  | 
    				yyerror("tag already defined"); | 
    ||
3903  | 
    free(yyvsp[0].v.string);  | 
    ||
3904  | 
    rule_free(rule);  | 
    ||
3905  | 
    free(rule);  | 
    ||
3906  | 
    YYERROR;  | 
    ||
3907  | 
    }  | 
    ||
3908  | 
    			if (tag == 0) { | 
    ||
3909  | 
    				yyerror("invalid tag"); | 
    ||
3910  | 
    free(yyvsp[0].v.string);  | 
    ||
3911  | 
    rule_free(rule);  | 
    ||
3912  | 
    free(rule);  | 
    ||
3913  | 
    YYERROR;  | 
    ||
3914  | 
    }  | 
    ||
3915  | 
    rule->rule_tag = tag;  | 
    ||
3916  | 
    if (strlcpy(rule->rule_tagname, yyvsp[0].v.string,  | 
    ||
3917  | 
    sizeof(rule->rule_tagname)) >=  | 
    ||
3918  | 
    			    sizeof(rule->rule_tagname)) { | 
    ||
3919  | 
    				yyerror("tag truncated"); | 
    ||
3920  | 
    free(yyvsp[0].v.string);  | 
    ||
3921  | 
    rule_free(rule);  | 
    ||
3922  | 
    free(rule);  | 
    ||
3923  | 
    YYERROR;  | 
    ||
3924  | 
    }  | 
    ||
3925  | 
    free(yyvsp[0].v.string);  | 
    ||
3926  | 
    }  | 
    ||
3927  | 
    break;  | 
    ||
3928  | 
    case 171:  | 
    ||
3929  | 
    #line 1499 "parse.y"  | 
    ||
3930  | 
    { | 
    ||
3931  | 
    			if (tag == 0) { | 
    ||
3932  | 
    				yyerror("no tag defined"); | 
    ||
3933  | 
    YYERROR;  | 
    ||
3934  | 
    }  | 
    ||
3935  | 
    rule->rule_tag = -1;  | 
    ||
3936  | 
    memset(rule->rule_tagname, 0,  | 
    ||
3937  | 
    sizeof(rule->rule_tagname));  | 
    ||
3938  | 
    }  | 
    ||
3939  | 
    break;  | 
    ||
3940  | 
    case 172:  | 
    ||
3941  | 
    #line 1508 "parse.y"  | 
    ||
3942  | 
    { | 
    ||
3943  | 
    tagged = tag_name2id(yyvsp[0].v.string);  | 
    ||
3944  | 
    			if (rule->rule_tagged) { | 
    ||
3945  | 
    				yyerror("tagged already defined"); | 
    ||
3946  | 
    free(yyvsp[0].v.string);  | 
    ||
3947  | 
    rule_free(rule);  | 
    ||
3948  | 
    free(rule);  | 
    ||
3949  | 
    YYERROR;  | 
    ||
3950  | 
    }  | 
    ||
3951  | 
    			if (tagged == 0) { | 
    ||
3952  | 
    				yyerror("invalid tag"); | 
    ||
3953  | 
    free(yyvsp[0].v.string);  | 
    ||
3954  | 
    rule_free(rule);  | 
    ||
3955  | 
    free(rule);  | 
    ||
3956  | 
    YYERROR;  | 
    ||
3957  | 
    }  | 
    ||
3958  | 
    rule->rule_tagged = tagged;  | 
    ||
3959  | 
    if (strlcpy(rule->rule_taggedname, yyvsp[0].v.string,  | 
    ||
3960  | 
    sizeof(rule->rule_taggedname)) >=  | 
    ||
3961  | 
    			    sizeof(rule->rule_taggedname)) { | 
    ||
3962  | 
    				yyerror("tagged truncated"); | 
    ||
3963  | 
    free(yyvsp[0].v.string);  | 
    ||
3964  | 
    rule_free(rule);  | 
    ||
3965  | 
    free(rule);  | 
    ||
3966  | 
    YYERROR;  | 
    ||
3967  | 
    }  | 
    ||
3968  | 
    free(yyvsp[0].v.string);  | 
    ||
3969  | 
    }  | 
    ||
3970  | 
    break;  | 
    ||
3971  | 
    case 173:  | 
    ||
3972  | 
    #line 1536 "parse.y"  | 
    ||
3973  | 
    { | 
    ||
3974  | 
    label = label_name2id(yyvsp[0].v.string);  | 
    ||
3975  | 
    			if (rule->rule_label) { | 
    ||
3976  | 
    				yyerror("label already defined"); | 
    ||
3977  | 
    free(yyvsp[0].v.string);  | 
    ||
3978  | 
    rule_free(rule);  | 
    ||
3979  | 
    free(rule);  | 
    ||
3980  | 
    YYERROR;  | 
    ||
3981  | 
    }  | 
    ||
3982  | 
    			if (label == 0) { | 
    ||
3983  | 
    				yyerror("invalid label"); | 
    ||
3984  | 
    free(yyvsp[0].v.string);  | 
    ||
3985  | 
    rule_free(rule);  | 
    ||
3986  | 
    free(rule);  | 
    ||
3987  | 
    YYERROR;  | 
    ||
3988  | 
    }  | 
    ||
3989  | 
    rule->rule_label = label;  | 
    ||
3990  | 
    if (strlcpy(rule->rule_labelname, yyvsp[0].v.string,  | 
    ||
3991  | 
    sizeof(rule->rule_labelname)) >=  | 
    ||
3992  | 
    			    sizeof(rule->rule_labelname)) { | 
    ||
3993  | 
    				yyerror("label truncated"); | 
    ||
3994  | 
    free(yyvsp[0].v.string);  | 
    ||
3995  | 
    rule_free(rule);  | 
    ||
3996  | 
    free(rule);  | 
    ||
3997  | 
    YYERROR;  | 
    ||
3998  | 
    }  | 
    ||
3999  | 
    free(yyvsp[0].v.string);  | 
    ||
4000  | 
    }  | 
    ||
4001  | 
    break;  | 
    ||
4002  | 
    case 174:  | 
    ||
4003  | 
    #line 1564 "parse.y"  | 
    ||
4004  | 
    { | 
    ||
4005  | 
    			if (label == 0) { | 
    ||
4006  | 
    				yyerror("no label defined"); | 
    ||
4007  | 
    YYERROR;  | 
    ||
4008  | 
    }  | 
    ||
4009  | 
    rule->rule_label = -1;  | 
    ||
4010  | 
    memset(rule->rule_labelname, 0,  | 
    ||
4011  | 
    sizeof(rule->rule_labelname));  | 
    ||
4012  | 
    }  | 
    ||
4013  | 
    break;  | 
    ||
4014  | 
    case 175:  | 
    ||
4015  | 
    #line 1573 "parse.y"  | 
    ||
4016  | 
    { | 
    ||
4017  | 
    			if (rulefile != NULL) { | 
    ||
4018  | 
    				yyerror("only one file per rule supported"); | 
    ||
4019  | 
    free(yyvsp[-1].v.string);  | 
    ||
4020  | 
    free(yyvsp[0].v.string);  | 
    ||
4021  | 
    rule_free(rule);  | 
    ||
4022  | 
    free(rule);  | 
    ||
4023  | 
    YYERROR;  | 
    ||
4024  | 
    }  | 
    ||
4025  | 
    			if (yyvsp[0].v.string) { | 
    ||
4026  | 
    if ((rule->rule_kv[keytype].kv_value =  | 
    ||
4027  | 
    strdup(yyvsp[0].v.string)) == NULL)  | 
    ||
4028  | 
    					fatal("out of memory"); | 
    ||
4029  | 
    free(yyvsp[0].v.string);  | 
    ||
4030  | 
    } else  | 
    ||
4031  | 
    rule->rule_kv[keytype].kv_value = NULL;  | 
    ||
4032  | 
    rulefile = yyvsp[-1].v.string;  | 
    ||
4033  | 
    }  | 
    ||
4034  | 
    break;  | 
    ||
4035  | 
    case 176:  | 
    ||
4036  | 
    #line 1593 "parse.y"  | 
    ||
4037  | 
    { yyval.v.string = NULL; } | 
    ||
4038  | 
    break;  | 
    ||
4039  | 
    case 177:  | 
    ||
4040  | 
    #line 1594 "parse.y"  | 
    ||
4041  | 
    { yyval.v.string = yyvsp[0].v.string; } | 
    ||
4042  | 
    break;  | 
    ||
4043  | 
    case 178:  | 
    ||
4044  | 
    #line 1597 "parse.y"  | 
    ||
4045  | 
    { yyval.v.number = KEY_OPTION_NONE; } | 
    ||
4046  | 
    break;  | 
    ||
4047  | 
    case 179:  | 
    ||
4048  | 
    #line 1598 "parse.y"  | 
    ||
4049  | 
    { yyval.v.number = KEY_OPTION_APPEND; } | 
    ||
4050  | 
    break;  | 
    ||
4051  | 
    case 180:  | 
    ||
4052  | 
    #line 1599 "parse.y"  | 
    ||
4053  | 
    { yyval.v.number = KEY_OPTION_SET; } | 
    ||
4054  | 
    break;  | 
    ||
4055  | 
    case 181:  | 
    ||
4056  | 
    #line 1600 "parse.y"  | 
    ||
4057  | 
    { yyval.v.number = KEY_OPTION_REMOVE; } | 
    ||
4058  | 
    break;  | 
    ||
4059  | 
    case 182:  | 
    ||
4060  | 
    #line 1601 "parse.y"  | 
    ||
4061  | 
    { yyval.v.number = KEY_OPTION_HASH; } | 
    ||
4062  | 
    break;  | 
    ||
4063  | 
    case 183:  | 
    ||
4064  | 
    #line 1602 "parse.y"  | 
    ||
4065  | 
    { yyval.v.number = KEY_OPTION_LOG; } | 
    ||
4066  | 
    break;  | 
    ||
4067  | 
    case 184:  | 
    ||
4068  | 
    #line 1605 "parse.y"  | 
    ||
4069  | 
    { | 
    ||
4070  | 
    struct relay *r;  | 
    ||
4071  | 
    |||
4072  | 
    			if (!loadcfg) { | 
    ||
4073  | 
    free(yyvsp[0].v.string);  | 
    ||
4074  | 
    YYACCEPT;  | 
    ||
4075  | 
    }  | 
    ||
4076  | 
    |||
4077  | 
    TAILQ_FOREACH(r, conf->sc_relays, rl_entry)  | 
    ||
4078  | 
    if (!strcmp(r->rl_conf.name, yyvsp[0].v.string))  | 
    ||
4079  | 
    break;  | 
    ||
4080  | 
    			if (r != NULL) { | 
    ||
4081  | 
    				yyerror("relay %s defined twice", yyvsp[0].v.string); | 
    ||
4082  | 
    free(yyvsp[0].v.string);  | 
    ||
4083  | 
    YYERROR;  | 
    ||
4084  | 
    }  | 
    ||
4085  | 
    TAILQ_INIT(&relays);  | 
    ||
4086  | 
    |||
4087  | 
    if ((r = calloc(1, sizeof (*r))) == NULL)  | 
    ||
4088  | 
    				fatal("out of memory"); | 
    ||
4089  | 
    |||
4090  | 
    if (strlcpy(r->rl_conf.name, yyvsp[0].v.string,  | 
    ||
4091  | 
    sizeof(r->rl_conf.name)) >=  | 
    ||
4092  | 
    			    sizeof(r->rl_conf.name)) { | 
    ||
4093  | 
    				yyerror("relay name truncated"); | 
    ||
4094  | 
    free(yyvsp[0].v.string);  | 
    ||
4095  | 
    free(r);  | 
    ||
4096  | 
    YYERROR;  | 
    ||
4097  | 
    }  | 
    ||
4098  | 
    free(yyvsp[0].v.string);  | 
    ||
4099  | 
    			if (relay_id(r) == -1) { | 
    ||
4100  | 
    				yyerror("too many relays defined"); | 
    ||
4101  | 
    free(r);  | 
    ||
4102  | 
    YYERROR;  | 
    ||
4103  | 
    }  | 
    ||
4104  | 
    r->rl_conf.timeout.tv_sec = RELAY_TIMEOUT;  | 
    ||
4105  | 
    r->rl_proto = NULL;  | 
    ||
4106  | 
    r->rl_conf.proto = EMPTY_ID;  | 
    ||
4107  | 
    r->rl_conf.dstretry = 0;  | 
    ||
4108  | 
    TAILQ_INIT(&r->rl_tables);  | 
    ||
4109  | 
    			if (last_relay_id == INT_MAX) { | 
    ||
4110  | 
    				yyerror("too many relays defined"); | 
    ||
4111  | 
    free(r);  | 
    ||
4112  | 
    YYERROR;  | 
    ||
4113  | 
    }  | 
    ||
4114  | 
    dstmode = RELAY_DSTMODE_DEFAULT;  | 
    ||
4115  | 
    rlay = r;  | 
    ||
4116  | 
    }  | 
    ||
4117  | 
    break;  | 
    ||
4118  | 
    case 185:  | 
    ||
4119  | 
    #line 1652 "parse.y"  | 
    ||
4120  | 
    { | 
    ||
4121  | 
    struct relay *r;  | 
    ||
4122  | 
    |||
4123  | 
    			if (rlay->rl_conf.ss.ss_family == AF_UNSPEC) { | 
    ||
4124  | 
    				yyerror("relay %s has no listener", | 
    ||
4125  | 
    rlay->rl_conf.name);  | 
    ||
4126  | 
    YYERROR;  | 
    ||
4127  | 
    }  | 
    ||
4128  | 
    if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) ==  | 
    ||
4129  | 
    			    (F_NATLOOK|F_DIVERT)) { | 
    ||
4130  | 
    				yyerror("relay %s with conflicting nat lookup " | 
    ||
4131  | 
    "and peer options", rlay->rl_conf.name);  | 
    ||
4132  | 
    YYERROR;  | 
    ||
4133  | 
    }  | 
    ||
4134  | 
    if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) == 0 &&  | 
    ||
4135  | 
    rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&  | 
    ||
4136  | 
    			    TAILQ_EMPTY(&rlay->rl_tables)) { | 
    ||
4137  | 
    				yyerror("relay %s has no target, rdr, " | 
    ||
4138  | 
    "or table", rlay->rl_conf.name);  | 
    ||
4139  | 
    YYERROR;  | 
    ||
4140  | 
    }  | 
    ||
4141  | 
    			if (rlay->rl_conf.proto == EMPTY_ID) { | 
    ||
4142  | 
    rlay->rl_proto = &conf->sc_proto_default;  | 
    ||
4143  | 
    rlay->rl_conf.proto = conf->sc_proto_default.id;  | 
    ||
4144  | 
    }  | 
    ||
4145  | 
    			if (relay_load_certfiles(rlay) == -1) { | 
    ||
4146  | 
    				yyerror("cannot load certificates for relay %s", | 
    ||
4147  | 
    rlay->rl_conf.name);  | 
    ||
4148  | 
    YYERROR;  | 
    ||
4149  | 
    }  | 
    ||
4150  | 
    conf->sc_relaycount++;  | 
    ||
4151  | 
    SPLAY_INIT(&rlay->rl_sessions);  | 
    ||
4152  | 
    TAILQ_INSERT_TAIL(conf->sc_relays, rlay, rl_entry);  | 
    ||
4153  | 
    |||
4154  | 
    tableport = 0;  | 
    ||
4155  | 
    |||
4156  | 
    			while ((r = TAILQ_FIRST(&relays)) != NULL) { | 
    ||
4157  | 
    TAILQ_REMOVE(&relays, r, rl_entry);  | 
    ||
4158  | 
    				if (relay_inherit(rlay, r) == NULL) { | 
    ||
4159  | 
    YYERROR;  | 
    ||
4160  | 
    }  | 
    ||
4161  | 
    }  | 
    ||
4162  | 
    rlay = NULL;  | 
    ||
4163  | 
    }  | 
    ||
4164  | 
    break;  | 
    ||
4165  | 
    case 188:  | 
    ||
4166  | 
    #line 1702 "parse.y"  | 
    ||
4167  | 
    { | 
    ||
4168  | 
    struct addresslist al;  | 
    ||
4169  | 
    struct address *h;  | 
    ||
4170  | 
    struct relay *r;  | 
    ||
4171  | 
    |||
4172  | 
    			if (rlay->rl_conf.ss.ss_family != AF_UNSPEC) { | 
    ||
4173  | 
    if ((r = calloc(1, sizeof (*r))) == NULL)  | 
    ||
4174  | 
    					fatal("out of memory"); | 
    ||
4175  | 
    TAILQ_INSERT_TAIL(&relays, r, rl_entry);  | 
    ||
4176  | 
    } else  | 
    ||
4177  | 
    r = rlay;  | 
    ||
4178  | 
    			if (yyvsp[-1].v.port.op != PF_OP_EQ) { | 
    ||
4179  | 
    				yyerror("invalid port"); | 
    ||
4180  | 
    free(yyvsp[-2].v.string);  | 
    ||
4181  | 
    YYERROR;  | 
    ||
4182  | 
    }  | 
    ||
4183  | 
    |||
4184  | 
    TAILQ_INIT(&al);  | 
    ||
4185  | 
    			if (host(yyvsp[-2].v.string, &al, 1, &yyvsp[-1].v.port, NULL, -1) <= 0) { | 
    ||
4186  | 
    				yyerror("invalid listen ip: %s", yyvsp[-2].v.string); | 
    ||
4187  | 
    free(yyvsp[-2].v.string);  | 
    ||
4188  | 
    YYERROR;  | 
    ||
4189  | 
    }  | 
    ||
4190  | 
    free(yyvsp[-2].v.string);  | 
    ||
4191  | 
    h = TAILQ_FIRST(&al);  | 
    ||
4192  | 
    bcopy(&h->ss, &r->rl_conf.ss, sizeof(r->rl_conf.ss));  | 
    ||
4193  | 
    r->rl_conf.port = h->port.val[0];  | 
    ||
4194  | 
    			if (yyvsp[0].v.number) { | 
    ||
4195  | 
    r->rl_conf.flags |= F_TLS;  | 
    ||
4196  | 
    conf->sc_conf.flags |= F_TLS;  | 
    ||
4197  | 
    }  | 
    ||
4198  | 
    tableport = h->port.val[0];  | 
    ||
4199  | 
    host_free(&al);  | 
    ||
4200  | 
    }  | 
    ||
4201  | 
    break;  | 
    ||
4202  | 
    case 189:  | 
    ||
4203  | 
    #line 1736 "parse.y"  | 
    ||
4204  | 
    { | 
    ||
4205  | 
    rlay->rl_conf.fwdmode = yyvsp[-4].v.number;  | 
    ||
4206  | 
    			if (yyvsp[-4].v.number == FWD_ROUTE) { | 
    ||
4207  | 
    				yyerror("no route for relays"); | 
    ||
4208  | 
    YYERROR;  | 
    ||
4209  | 
    }  | 
    ||
4210  | 
    			if (yyvsp[-3].v.number) { | 
    ||
4211  | 
    rlay->rl_conf.flags |= F_TLSCLIENT;  | 
    ||
4212  | 
    conf->sc_conf.flags |= F_TLSCLIENT;  | 
    ||
4213  | 
    }  | 
    ||
4214  | 
    }  | 
    ||
4215  | 
    break;  | 
    ||
4216  | 
    case 190:  | 
    ||
4217  | 
    #line 1747 "parse.y"  | 
    ||
4218  | 
    { | 
    ||
4219  | 
    			if ((rlay->rl_conf.timeout.tv_sec = yyvsp[0].v.number) < 0) { | 
    ||
4220  | 
    				yyerror("invalid timeout: %lld", yyvsp[0].v.number); | 
    ||
4221  | 
    YYERROR;  | 
    ||
4222  | 
    }  | 
    ||
4223  | 
    			if (rlay->rl_conf.timeout.tv_sec > INT_MAX) { | 
    ||
4224  | 
    				yyerror("timeout too large: %lld", yyvsp[0].v.number); | 
    ||
4225  | 
    YYERROR;  | 
    ||
4226  | 
    }  | 
    ||
4227  | 
    }  | 
    ||
4228  | 
    break;  | 
    ||
4229  | 
    case 191:  | 
    ||
4230  | 
    #line 1757 "parse.y"  | 
    ||
4231  | 
    { | 
    ||
4232  | 
    struct protocol *p;  | 
    ||
4233  | 
    |||
4234  | 
    TAILQ_FOREACH(p, conf->sc_protos, entry)  | 
    ||
4235  | 
    if (!strcmp(p->name, yyvsp[0].v.string))  | 
    ||
4236  | 
    break;  | 
    ||
4237  | 
    			if (p == NULL) { | 
    ||
4238  | 
    				yyerror("no such protocol: %s", yyvsp[0].v.string); | 
    ||
4239  | 
    free(yyvsp[0].v.string);  | 
    ||
4240  | 
    YYERROR;  | 
    ||
4241  | 
    }  | 
    ||
4242  | 
    p->flags |= F_USED;  | 
    ||
4243  | 
    rlay->rl_conf.proto = p->id;  | 
    ||
4244  | 
    rlay->rl_proto = p;  | 
    ||
4245  | 
    free(yyvsp[0].v.string);  | 
    ||
4246  | 
    }  | 
    ||
4247  | 
    break;  | 
    ||
4248  | 
    case 192:  | 
    ||
4249  | 
    #line 1773 "parse.y"  | 
    ||
4250  | 
    { rlay->rl_conf.flags |= F_DISABLE; } | 
    ||
4251  | 
    break;  | 
    ||
4252  | 
    case 194:  | 
    ||
4253  | 
    #line 1777 "parse.y"  | 
    ||
4254  | 
    { | 
    ||
4255  | 
    struct addresslist al;  | 
    ||
4256  | 
    struct address *h;  | 
    ||
4257  | 
    |||
4258  | 
    			if (rlay->rl_conf.dstss.ss_family != AF_UNSPEC) { | 
    ||
4259  | 
    				yyerror("relay %s target or redirection " | 
    ||
4260  | 
    "already specified", rlay->rl_conf.name);  | 
    ||
4261  | 
    free(yyvsp[-2].v.string);  | 
    ||
4262  | 
    YYERROR;  | 
    ||
4263  | 
    }  | 
    ||
4264  | 
    			if (yyvsp[-1].v.port.op != PF_OP_EQ) { | 
    ||
4265  | 
    				yyerror("invalid port"); | 
    ||
4266  | 
    free(yyvsp[-2].v.string);  | 
    ||
4267  | 
    YYERROR;  | 
    ||
4268  | 
    }  | 
    ||
4269  | 
    |||
4270  | 
    TAILQ_INIT(&al);  | 
    ||
4271  | 
    			if (host(yyvsp[-2].v.string, &al, 1, &yyvsp[-1].v.port, NULL, -1) <= 0) { | 
    ||
4272  | 
    				yyerror("invalid listen ip: %s", yyvsp[-2].v.string); | 
    ||
4273  | 
    free(yyvsp[-2].v.string);  | 
    ||
4274  | 
    YYERROR;  | 
    ||
4275  | 
    }  | 
    ||
4276  | 
    free(yyvsp[-2].v.string);  | 
    ||
4277  | 
    h = TAILQ_FIRST(&al);  | 
    ||
4278  | 
    bcopy(&h->ss, &rlay->rl_conf.dstss,  | 
    ||
4279  | 
    sizeof(rlay->rl_conf.dstss));  | 
    ||
4280  | 
    rlay->rl_conf.dstport = h->port.val[0];  | 
    ||
4281  | 
    rlay->rl_conf.dstretry = yyvsp[0].v.number;  | 
    ||
4282  | 
    host_free(&al);  | 
    ||
4283  | 
    }  | 
    ||
4284  | 
    break;  | 
    ||
4285  | 
    case 195:  | 
    ||
4286  | 
    #line 1807 "parse.y"  | 
    ||
4287  | 
    { | 
    ||
4288  | 
    conf->sc_conf.flags |= F_NEEDPF;  | 
    ||
4289  | 
    rlay->rl_conf.flags |= F_NATLOOK;  | 
    ||
4290  | 
    rlay->rl_conf.dstretry = yyvsp[0].v.number;  | 
    ||
4291  | 
    }  | 
    ||
4292  | 
    break;  | 
    ||
4293  | 
    case 196:  | 
    ||
4294  | 
    #line 1812 "parse.y"  | 
    ||
4295  | 
    { | 
    ||
4296  | 
    conf->sc_conf.flags |= F_NEEDPF;  | 
    ||
4297  | 
    rlay->rl_conf.flags |= F_DIVERT;  | 
    ||
4298  | 
    rlay->rl_conf.dstretry = yyvsp[0].v.number;  | 
    ||
4299  | 
    }  | 
    ||
4300  | 
    break;  | 
    ||
4301  | 
    case 197:  | 
    ||
4302  | 
    #line 1817 "parse.y"  | 
    ||
4303  | 
    { | 
    ||
4304  | 
    struct relay_table *rlt;  | 
    ||
4305  | 
    |||
4306  | 
    			if ((rlt = calloc(1, sizeof(*rlt))) == NULL) { | 
    ||
4307  | 
    				yyerror("failed to allocate table reference"); | 
    ||
4308  | 
    YYERROR;  | 
    ||
4309  | 
    }  | 
    ||
4310  | 
    |||
4311  | 
    rlt->rlt_table = yyvsp[0].v.table;  | 
    ||
4312  | 
    rlt->rlt_table->conf.flags |= F_USED;  | 
    ||
4313  | 
    rlt->rlt_mode = dstmode;  | 
    ||
4314  | 
    rlt->rlt_flags = F_USED;  | 
    ||
4315  | 
    if (!TAILQ_EMPTY(&rlay->rl_tables))  | 
    ||
4316  | 
    rlt->rlt_flags |= F_BACKUP;  | 
    ||
4317  | 
    |||
4318  | 
    if (hashkey != NULL &&  | 
    ||
4319  | 
    			    (rlay->rl_conf.flags & F_HASHKEY) == 0) { | 
    ||
4320  | 
    memcpy(&rlay->rl_conf.hashkey,  | 
    ||
4321  | 
    hashkey, sizeof(rlay->rl_conf.hashkey));  | 
    ||
4322  | 
    rlay->rl_conf.flags |= F_HASHKEY;  | 
    ||
4323  | 
    }  | 
    ||
4324  | 
    free(hashkey);  | 
    ||
4325  | 
    hashkey = NULL;  | 
    ||
4326  | 
    |||
4327  | 
    TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry);  | 
    ||
4328  | 
    }  | 
    ||
4329  | 
    break;  | 
    ||
4330  | 
    case 198:  | 
    ||
4331  | 
    #line 1845 "parse.y"  | 
    ||
4332  | 
    { yyval.v.number = RELAY_DSTMODE_DEFAULT; } | 
    ||
4333  | 
    break;  | 
    ||
4334  | 
    case 199:  | 
    ||
4335  | 
    #line 1846 "parse.y"  | 
    ||
4336  | 
    { yyval.v.number = RELAY_DSTMODE_LOADBALANCE; } | 
    ||
4337  | 
    break;  | 
    ||
4338  | 
    case 200:  | 
    ||
4339  | 
    #line 1847 "parse.y"  | 
    ||
4340  | 
    { yyval.v.number = RELAY_DSTMODE_ROUNDROBIN; } | 
    ||
4341  | 
    break;  | 
    ||
4342  | 
    case 201:  | 
    ||
4343  | 
    #line 1848 "parse.y"  | 
    ||
4344  | 
    { yyval.v.number = RELAY_DSTMODE_HASH; } | 
    ||
4345  | 
    break;  | 
    ||
4346  | 
    case 202:  | 
    ||
4347  | 
    #line 1849 "parse.y"  | 
    ||
4348  | 
    { yyval.v.number = RELAY_DSTMODE_LEASTSTATES; } | 
    ||
4349  | 
    break;  | 
    ||
4350  | 
    case 203:  | 
    ||
4351  | 
    #line 1850 "parse.y"  | 
    ||
4352  | 
    { yyval.v.number = RELAY_DSTMODE_SRCHASH; } | 
    ||
4353  | 
    break;  | 
    ||
4354  | 
    case 204:  | 
    ||
4355  | 
    #line 1851 "parse.y"  | 
    ||
4356  | 
    { yyval.v.number = RELAY_DSTMODE_RANDOM; } | 
    ||
4357  | 
    break;  | 
    ||
4358  | 
    case 205:  | 
    ||
4359  | 
    #line 1854 "parse.y"  | 
    ||
4360  | 
    { | 
    ||
4361  | 
    struct router *rt = NULL;  | 
    ||
4362  | 
    |||
4363  | 
    			if (!loadcfg) { | 
    ||
4364  | 
    free(yyvsp[0].v.string);  | 
    ||
4365  | 
    YYACCEPT;  | 
    ||
4366  | 
    }  | 
    ||
4367  | 
    |||
4368  | 
    conf->sc_conf.flags |= F_NEEDRT;  | 
    ||
4369  | 
    TAILQ_FOREACH(rt, conf->sc_rts, rt_entry)  | 
    ||
4370  | 
    if (!strcmp(rt->rt_conf.name, yyvsp[0].v.string))  | 
    ||
4371  | 
    break;  | 
    ||
4372  | 
    			if (rt != NULL) { | 
    ||
4373  | 
    				yyerror("router %s defined twice", yyvsp[0].v.string); | 
    ||
4374  | 
    free(yyvsp[0].v.string);  | 
    ||
4375  | 
    YYERROR;  | 
    ||
4376  | 
    }  | 
    ||
4377  | 
    |||
4378  | 
    if ((rt = calloc(1, sizeof (*rt))) == NULL)  | 
    ||
4379  | 
    				fatal("out of memory"); | 
    ||
4380  | 
    |||
4381  | 
    if (strlcpy(rt->rt_conf.name, yyvsp[0].v.string,  | 
    ||
4382  | 
    sizeof(rt->rt_conf.name)) >=  | 
    ||
4383  | 
    			    sizeof(rt->rt_conf.name)) { | 
    ||
4384  | 
    				yyerror("router name truncated"); | 
    ||
4385  | 
    free(rt);  | 
    ||
4386  | 
    YYERROR;  | 
    ||
4387  | 
    }  | 
    ||
4388  | 
    free(yyvsp[0].v.string);  | 
    ||
4389  | 
    rt->rt_conf.id = ++last_rt_id;  | 
    ||
4390  | 
    			if (last_rt_id == INT_MAX) { | 
    ||
4391  | 
    				yyerror("too many routers defined"); | 
    ||
4392  | 
    free(rt);  | 
    ||
4393  | 
    YYERROR;  | 
    ||
4394  | 
    }  | 
    ||
4395  | 
    TAILQ_INIT(&rt->rt_netroutes);  | 
    ||
4396  | 
    router = rt;  | 
    ||
4397  | 
    |||
4398  | 
    tableport = -1;  | 
    ||
4399  | 
    }  | 
    ||
4400  | 
    break;  | 
    ||
4401  | 
    case 206:  | 
    ||
4402  | 
    #line 1893 "parse.y"  | 
    ||
4403  | 
    { | 
    ||
4404  | 
    			if (!router->rt_conf.nroutes) { | 
    ||
4405  | 
    				yyerror("router %s without routes", | 
    ||
4406  | 
    router->rt_conf.name);  | 
    ||
4407  | 
    free(router);  | 
    ||
4408  | 
    router = NULL;  | 
    ||
4409  | 
    YYERROR;  | 
    ||
4410  | 
    }  | 
    ||
4411  | 
    |||
4412  | 
    conf->sc_routercount++;  | 
    ||
4413  | 
    TAILQ_INSERT_TAIL(conf->sc_rts, router, rt_entry);  | 
    ||
4414  | 
    router = NULL;  | 
    ||
4415  | 
    |||
4416  | 
    tableport = 0;  | 
    ||
4417  | 
    }  | 
    ||
4418  | 
    break;  | 
    ||
4419  | 
    case 209:  | 
    ||
4420  | 
    #line 1914 "parse.y"  | 
    ||
4421  | 
    { | 
    ||
4422  | 
    struct netroute *nr;  | 
    ||
4423  | 
    |||
4424  | 
    if (router->rt_conf.af == AF_UNSPEC)  | 
    ||
4425  | 
    router->rt_conf.af = yyvsp[-2].v.addr.ss.ss_family;  | 
    ||
4426  | 
    			else if (router->rt_conf.af != yyvsp[-2].v.addr.ss.ss_family) { | 
    ||
4427  | 
    				yyerror("router %s address family mismatch", | 
    ||
4428  | 
    router->rt_conf.name);  | 
    ||
4429  | 
    YYERROR;  | 
    ||
4430  | 
    }  | 
    ||
4431  | 
    |||
4432  | 
    if ((router->rt_conf.af == AF_INET &&  | 
    ||
4433  | 
    (yyvsp[0].v.number > 32 || yyvsp[0].v.number < 0)) ||  | 
    ||
4434  | 
    (router->rt_conf.af == AF_INET6 &&  | 
    ||
4435  | 
    			    (yyvsp[0].v.number > 128 || yyvsp[0].v.number < 0))) { | 
    ||
4436  | 
    				yyerror("invalid prefixlen %d", yyvsp[0].v.number); | 
    ||
4437  | 
    YYERROR;  | 
    ||
4438  | 
    }  | 
    ||
4439  | 
    |||
4440  | 
    if ((nr = calloc(1, sizeof(*nr))) == NULL)  | 
    ||
4441  | 
    				fatal("out of memory"); | 
    ||
4442  | 
    |||
4443  | 
    nr->nr_conf.id = ++last_nr_id;  | 
    ||
4444  | 
    			if (last_nr_id == INT_MAX) { | 
    ||
4445  | 
    				yyerror("too many routes defined"); | 
    ||
4446  | 
    free(nr);  | 
    ||
4447  | 
    YYERROR;  | 
    ||
4448  | 
    }  | 
    ||
4449  | 
    nr->nr_conf.prefixlen = yyvsp[0].v.number;  | 
    ||
4450  | 
    nr->nr_conf.routerid = router->rt_conf.id;  | 
    ||
4451  | 
    nr->nr_router = router;  | 
    ||
4452  | 
    bcopy(&yyvsp[-2].v.addr.ss, &nr->nr_conf.ss, sizeof(yyvsp[-2].v.addr.ss));  | 
    ||
4453  | 
    |||
4454  | 
    router->rt_conf.nroutes++;  | 
    ||
4455  | 
    conf->sc_routecount++;  | 
    ||
4456  | 
    TAILQ_INSERT_TAIL(&router->rt_netroutes, nr, nr_entry);  | 
    ||
4457  | 
    TAILQ_INSERT_TAIL(conf->sc_routes, nr, nr_route);  | 
    ||
4458  | 
    }  | 
    ||
4459  | 
    break;  | 
    ||
4460  | 
    case 210:  | 
    ||
4461  | 
    #line 1952 "parse.y"  | 
    ||
4462  | 
    { | 
    ||
4463  | 
    free(hashkey);  | 
    ||
4464  | 
    hashkey = NULL;  | 
    ||
4465  | 
    |||
4466  | 
    			if (router->rt_gwtable) { | 
    ||
4467  | 
    				yyerror("router %s table already specified", | 
    ||
4468  | 
    router->rt_conf.name);  | 
    ||
4469  | 
    purge_table(conf, conf->sc_tables, yyvsp[0].v.table);  | 
    ||
4470  | 
    YYERROR;  | 
    ||
4471  | 
    }  | 
    ||
4472  | 
    router->rt_gwtable = yyvsp[0].v.table;  | 
    ||
4473  | 
    router->rt_gwtable->conf.flags |= F_USED;  | 
    ||
4474  | 
    router->rt_conf.gwtable = yyvsp[0].v.table->conf.id;  | 
    ||
4475  | 
    router->rt_conf.gwport = yyvsp[0].v.table->conf.port;  | 
    ||
4476  | 
    }  | 
    ||
4477  | 
    break;  | 
    ||
4478  | 
    case 211:  | 
    ||
4479  | 
    #line 1967 "parse.y"  | 
    ||
4480  | 
    { | 
    ||
4481  | 
    			if (router->rt_conf.rtable) { | 
    ||
4482  | 
    				yyerror("router %s rtable already specified", | 
    ||
4483  | 
    router->rt_conf.name);  | 
    ||
4484  | 
    YYERROR;  | 
    ||
4485  | 
    }  | 
    ||
4486  | 
    			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RT_TABLEID_MAX) { | 
    ||
4487  | 
    				yyerror("invalid rtable id %d", yyvsp[0].v.number); | 
    ||
4488  | 
    YYERROR;  | 
    ||
4489  | 
    }  | 
    ||
4490  | 
    router->rt_conf.rtable = yyvsp[0].v.number;  | 
    ||
4491  | 
    }  | 
    ||
4492  | 
    break;  | 
    ||
4493  | 
    case 212:  | 
    ||
4494  | 
    #line 1979 "parse.y"  | 
    ||
4495  | 
    { | 
    ||
4496  | 
    if (strlcpy(router->rt_conf.label, yyvsp[0].v.string,  | 
    ||
4497  | 
    sizeof(router->rt_conf.label)) >=  | 
    ||
4498  | 
    			    sizeof(router->rt_conf.label)) { | 
    ||
4499  | 
    				yyerror("route label truncated"); | 
    ||
4500  | 
    free(yyvsp[0].v.string);  | 
    ||
4501  | 
    YYERROR;  | 
    ||
4502  | 
    }  | 
    ||
4503  | 
    free(yyvsp[0].v.string);  | 
    ||
4504  | 
    }  | 
    ||
4505  | 
    break;  | 
    ||
4506  | 
    case 213:  | 
    ||
4507  | 
    #line 1989 "parse.y"  | 
    ||
4508  | 
    { rlay->rl_conf.flags |= F_DISABLE; } | 
    ||
4509  | 
    break;  | 
    ||
4510  | 
    case 215:  | 
    ||
4511  | 
    #line 1993 "parse.y"  | 
    ||
4512  | 
    { | 
    ||
4513  | 
    rlay->rl_conf.dstaf.ss_family = AF_UNSPEC;  | 
    ||
4514  | 
    }  | 
    ||
4515  | 
    break;  | 
    ||
4516  | 
    case 216:  | 
    ||
4517  | 
    #line 1996 "parse.y"  | 
    ||
4518  | 
    { | 
    ||
4519  | 
    rlay->rl_conf.dstaf.ss_family = AF_INET;  | 
    ||
4520  | 
    }  | 
    ||
4521  | 
    break;  | 
    ||
4522  | 
    case 217:  | 
    ||
4523  | 
    #line 1999 "parse.y"  | 
    ||
4524  | 
    { | 
    ||
4525  | 
    struct sockaddr_in6 *sin6;  | 
    ||
4526  | 
    |||
4527  | 
    sin6 = (struct sockaddr_in6 *)&rlay->rl_conf.dstaf;  | 
    ||
4528  | 
    			if (inet_pton(AF_INET6, yyvsp[0].v.string, &sin6->sin6_addr) == -1) { | 
    ||
4529  | 
    				yyerror("invalid ipv6 address %s", yyvsp[0].v.string); | 
    ||
4530  | 
    free(yyvsp[0].v.string);  | 
    ||
4531  | 
    YYERROR;  | 
    ||
4532  | 
    }  | 
    ||
4533  | 
    free(yyvsp[0].v.string);  | 
    ||
4534  | 
    |||
4535  | 
    sin6->sin6_family = AF_INET6;  | 
    ||
4536  | 
    sin6->sin6_len = sizeof(*sin6);  | 
    ||
4537  | 
    }  | 
    ||
4538  | 
    break;  | 
    ||
4539  | 
    case 218:  | 
    ||
4540  | 
    #line 2015 "parse.y"  | 
    ||
4541  | 
    { yyval.v.string = NULL; } | 
    ||
4542  | 
    break;  | 
    ||
4543  | 
    case 219:  | 
    ||
4544  | 
    #line 2016 "parse.y"  | 
    ||
4545  | 
    { yyval.v.string = yyvsp[0].v.string; } | 
    ||
4546  | 
    break;  | 
    ||
4547  | 
    case 220:  | 
    ||
4548  | 
    #line 2019 "parse.y"  | 
    ||
4549  | 
    { | 
    ||
4550  | 
    if ((hst = calloc(1, sizeof(*(hst)))) == NULL)  | 
    ||
4551  | 
    				fatal("out of memory"); | 
    ||
4552  | 
    |||
4553  | 
    if (strlcpy(hst->conf.name, yyvsp[0].v.addr.name,  | 
    ||
4554  | 
    			    sizeof(hst->conf.name)) >= sizeof(hst->conf.name)) { | 
    ||
4555  | 
    				yyerror("host name truncated"); | 
    ||
4556  | 
    free(hst);  | 
    ||
4557  | 
    YYERROR;  | 
    ||
4558  | 
    }  | 
    ||
4559  | 
    bcopy(&yyvsp[0].v.addr.ss, &hst->conf.ss, sizeof(yyvsp[0].v.addr.ss));  | 
    ||
4560  | 
    hst->conf.id = 0; /* will be set later */  | 
    ||
4561  | 
    SLIST_INIT(&hst->children);  | 
    ||
4562  | 
    }  | 
    ||
4563  | 
    break;  | 
    ||
4564  | 
    case 221:  | 
    ||
4565  | 
    #line 2032 "parse.y"  | 
    ||
4566  | 
    { | 
    ||
4567  | 
    yyval.v.host = hst;  | 
    ||
4568  | 
    hst = NULL;  | 
    ||
4569  | 
    }  | 
    ||
4570  | 
    break;  | 
    ||
4571  | 
    case 226:  | 
    ||
4572  | 
    #line 2046 "parse.y"  | 
    ||
4573  | 
    { | 
    ||
4574  | 
    			if (hst->conf.retry) { | 
    ||
4575  | 
    				yyerror("retry value already set"); | 
    ||
4576  | 
    YYERROR;  | 
    ||
4577  | 
    }  | 
    ||
4578  | 
    			if (yyvsp[0].v.number < 0) { | 
    ||
4579  | 
    				yyerror("invalid retry value: %d\n", yyvsp[0].v.number); | 
    ||
4580  | 
    YYERROR;  | 
    ||
4581  | 
    }  | 
    ||
4582  | 
    hst->conf.retry = yyvsp[0].v.number;  | 
    ||
4583  | 
    }  | 
    ||
4584  | 
    break;  | 
    ||
4585  | 
    case 227:  | 
    ||
4586  | 
    #line 2057 "parse.y"  | 
    ||
4587  | 
    { | 
    ||
4588  | 
    			if (hst->conf.parentid) { | 
    ||
4589  | 
    				yyerror("parent value already set"); | 
    ||
4590  | 
    YYERROR;  | 
    ||
4591  | 
    }  | 
    ||
4592  | 
    			if (yyvsp[0].v.number < 0) { | 
    ||
4593  | 
    				yyerror("invalid parent value: %d\n", yyvsp[0].v.number); | 
    ||
4594  | 
    YYERROR;  | 
    ||
4595  | 
    }  | 
    ||
4596  | 
    hst->conf.parentid = yyvsp[0].v.number;  | 
    ||
4597  | 
    }  | 
    ||
4598  | 
    break;  | 
    ||
4599  | 
    case 228:  | 
    ||
4600  | 
    #line 2068 "parse.y"  | 
    ||
4601  | 
    { | 
    ||
4602  | 
    			if (hst->conf.priority) { | 
    ||
4603  | 
    				yyerror("priority already set"); | 
    ||
4604  | 
    YYERROR;  | 
    ||
4605  | 
    }  | 
    ||
4606  | 
    			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RTP_MAX) { | 
    ||
4607  | 
    				yyerror("invalid priority value: %d\n", yyvsp[0].v.number); | 
    ||
4608  | 
    YYERROR;  | 
    ||
4609  | 
    }  | 
    ||
4610  | 
    hst->conf.priority = yyvsp[0].v.number;  | 
    ||
4611  | 
    }  | 
    ||
4612  | 
    break;  | 
    ||
4613  | 
    case 229:  | 
    ||
4614  | 
    #line 2079 "parse.y"  | 
    ||
4615  | 
    { | 
    ||
4616  | 
    			if (hst->conf.ttl) { | 
    ||
4617  | 
    				yyerror("ttl value already set"); | 
    ||
4618  | 
    YYERROR;  | 
    ||
4619  | 
    }  | 
    ||
4620  | 
    			if (yyvsp[0].v.number < 0) { | 
    ||
4621  | 
    				yyerror("invalid ttl value: %d\n", yyvsp[0].v.number); | 
    ||
4622  | 
    YYERROR;  | 
    ||
4623  | 
    }  | 
    ||
4624  | 
    hst->conf.ttl = yyvsp[0].v.number;  | 
    ||
4625  | 
    }  | 
    ||
4626  | 
    break;  | 
    ||
4627  | 
    case 230:  | 
    ||
4628  | 
    #line 2092 "parse.y"  | 
    ||
4629  | 
    { | 
    ||
4630  | 
    struct address *h;  | 
    ||
4631  | 
    struct addresslist al;  | 
    ||
4632  | 
    |||
4633  | 
    if (strlcpy(yyval.v.addr.name, yyvsp[0].v.string,  | 
    ||
4634  | 
    			    sizeof(yyval.v.addr.name)) >= sizeof(yyval.v.addr.name)) { | 
    ||
4635  | 
    				yyerror("host name truncated"); | 
    ||
4636  | 
    free(yyvsp[0].v.string);  | 
    ||
4637  | 
    YYERROR;  | 
    ||
4638  | 
    }  | 
    ||
4639  | 
    |||
4640  | 
    TAILQ_INIT(&al);  | 
    ||
4641  | 
    			if (host(yyvsp[0].v.string, &al, 1, NULL, NULL, -1) <= 0) { | 
    ||
4642  | 
    				yyerror("invalid host %s", yyvsp[0].v.string); | 
    ||
4643  | 
    free(yyvsp[0].v.string);  | 
    ||
4644  | 
    YYERROR;  | 
    ||
4645  | 
    }  | 
    ||
4646  | 
    free(yyvsp[0].v.string);  | 
    ||
4647  | 
    h = TAILQ_FIRST(&al);  | 
    ||
4648  | 
    memcpy(&yyval.v.addr.ss, &h->ss, sizeof(yyval.v.addr.ss));  | 
    ||
4649  | 
    host_free(&al);  | 
    ||
4650  | 
    }  | 
    ||
4651  | 
    break;  | 
    ||
4652  | 
    case 231:  | 
    ||
4653  | 
    #line 2116 "parse.y"  | 
    ||
4654  | 
    { yyval.v.number = 0; } | 
    ||
4655  | 
    break;  | 
    ||
4656  | 
    case 232:  | 
    ||
4657  | 
    #line 2117 "parse.y"  | 
    ||
4658  | 
    { | 
    ||
4659  | 
    			if ((yyval.v.number = yyvsp[0].v.number) < 0) { | 
    ||
4660  | 
    				yyerror("invalid retry value: %d\n", yyvsp[0].v.number); | 
    ||
4661  | 
    YYERROR;  | 
    ||
4662  | 
    }  | 
    ||
4663  | 
    }  | 
    ||
4664  | 
    break;  | 
    ||
4665  | 
    case 233:  | 
    ||
4666  | 
    #line 2126 "parse.y"  | 
    ||
4667  | 
    { | 
    ||
4668  | 
    			if (yyvsp[0].v.number < 0) { | 
    ||
4669  | 
    				yyerror("invalid timeout: %d\n", yyvsp[0].v.number); | 
    ||
4670  | 
    YYERROR;  | 
    ||
4671  | 
    }  | 
    ||
4672  | 
    yyval.v.tv.tv_sec = yyvsp[0].v.number / 1000;  | 
    ||
4673  | 
    yyval.v.tv.tv_usec = (yyvsp[0].v.number % 1000) * 1000;  | 
    ||
4674  | 
    }  | 
    ||
4675  | 
    break;  | 
    ||
4676  | 
    case 240:  | 
    ||
4677  | 
    #line 2148 "parse.y"  | 
    ||
4678  | 
    42252  | 
    { yyval.v.string = yyvsp[0].v.string; } | 
    |
4679  | 
    42252  | 
    break;  | 
    |
4680  | 
    42252  | 
    case 241:  | 
    |
4681  | 
    42252  | 
    #line 2149 "parse.y"  | 
    |
4682  | 
    ✓✓ | 42252  | 
    { yyval.v.string = NULL; } | 
    
4683  | 
    break;  | 
    ||
4684  | 
    #line 4677 "parse.c"  | 
    ||
4685  | 
    }  | 
    ||
4686  | 
    yyssp -= yym;  | 
    ||
4687  | 
    yystate = *yyssp;  | 
    ||
4688  | 
    yyvsp -= yym;  | 
    ||
4689  | 
    yym = yylhs[yyn];  | 
    ||
4690  | 
    4440  | 
    if (yystate == 0 && yym == 0)  | 
    |
4691  | 
    4440  | 
        { | 
    |
4692  | 
    ✓✗ | 4440  | 
    #if YYDEBUG  | 
    
4693  | 
    if (yydebug)  | 
    ||
4694  | 
    4440  | 
                printf("%sdebug: after reduction, shifting from state 0 to\ | 
    |
4695  | 
    state %d\n", YYPREFIX, YYFINAL);  | 
    ||
4696  | 
    #endif  | 
    ||
4697  | 
    yystate = YYFINAL;  | 
    ||
4698  | 
    *++yyssp = YYFINAL;  | 
    ||
4699  | 
    *++yyvsp = yyval;  | 
    ||
4700  | 
    if (yychar < 0)  | 
    ||
4701  | 
            { | 
    ||
4702  | 
    if ((yychar = yylex()) < 0) yychar = 0;  | 
    ||
4703  | 
    #if YYDEBUG  | 
    ||
4704  | 
    if (yydebug)  | 
    ||
4705  | 
    4440  | 
                { | 
    |
4706  | 
    ✓✓ | 4440  | 
    yys = 0;  | 
    
4707  | 
    3892  | 
    if (yychar <= YYMAXTOKEN) yys = yyname[yychar];  | 
    |
4708  | 
    if (!yys) yys = "illegal-symbol";  | 
    ||
4709  | 
    ✓✓✓✗ ✓✓  | 
    90660  | 
                    printf("%sdebug: state %d, reading %d (%s)\n", | 
    
4710  | 
    35232  | 
    YYPREFIX, YYFINAL, yychar, yys);  | 
    |
4711  | 
    15112  | 
    }  | 
    |
4712  | 
    #endif  | 
    ||
4713  | 
    22700  | 
    }  | 
    |
4714  | 
    if (yychar == 0) goto yyaccept;  | 
    ||
4715  | 
    goto yyloop;  | 
    ||
4716  | 
    }  | 
    ||
4717  | 
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&  | 
    ||
4718  | 
    yyn <= YYTABLESIZE && yycheck[yyn] == yystate)  | 
    ||
4719  | 
    ✗✓✗✗ | 
    37812  | 
    yystate = yytable[yyn];  | 
    
4720  | 
    else  | 
    ||
4721  | 
    yystate = yydgoto[yym];  | 
    ||
4722  | 
    #if YYDEBUG  | 
    ||
4723  | 
    37812  | 
    if (yydebug)  | 
    |
4724  | 
    37812  | 
            printf("%sdebug: after reduction, shifting from state %d \ | 
    |
4725  | 
    37812  | 
    to state %d\n", YYPREFIX, *yyssp, yystate);  | 
    |
4726  | 
    #endif  | 
    ||
4727  | 
    if (yyssp >= yysslim && yygrowstack())  | 
    ||
4728  | 
        { | 
    ||
4729  | 
    goto yyoverflow;  | 
    ||
4730  | 
    }  | 
    ||
4731  | 
    *++yyssp = yystate;  | 
    ||
4732  | 
    *++yyvsp = yyval;  | 
    ||
4733  | 
    goto yyloop;  | 
    ||
4734  | 
    yyoverflow:  | 
    ||
4735  | 
        yyerror("yacc stack overflow"); | 
    ||
4736  | 
    yyabort:  | 
    ||
4737  | 
    if (yyss)  | 
    ||
4738  | 
    ✓✗ | 1104  | 
    free(yyss);  | 
    
4739  | 
    1104  | 
    if (yyvs)  | 
    |
4740  | 
    ✓✗ | 1104  | 
    free(yyvs);  | 
    
4741  | 
    1104  | 
    yyss = yyssp = NULL;  | 
    |
4742  | 
    1104  | 
    yyvs = yyvsp = NULL;  | 
    |
4743  | 
    1104  | 
    yystacksize = 0;  | 
    |
4744  | 
    1104  | 
    return (1);  | 
    |
4745  | 
    1104  | 
    yyaccept:  | 
    |
4746  | 
    1104  | 
    if (yyss)  | 
    |
4747  | 
    free(yyss);  | 
    ||
4748  | 
    if (yyvs)  | 
    ||
4749  | 
    free(yyvs);  | 
    ||
4750  | 
    yyss = yyssp = NULL;  | 
    ||
4751  | 
    yyvs = yyvsp = NULL;  | 
    ||
4752  | 
    yystacksize = 0;  | 
    ||
4753  | 
    return (0);  | 
    ||
4754  | 
    }  | 
    
| Generated by: GCOVR (Version 3.3) |