Bug Summary

File:src/usr.sbin/relayd/obj/parse.c
Warning:line 3082, column 5
Potential leak of memory pointed to by 'tb'

Annotated Source Code

Press '?' to see keyboard shortcuts

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