Browse code

core: config parser listen if names fix

If no quotes were used in listen=x, it was assumed that x was an
ip or a valid hostname (each domain part starts with a letter,
numbers and '_' are not allowed as first chars). However this
assumption failed when interface names were used, e.g. eth0.1 is a
valid interface name, but listen=eth0.1 resulted in error (it
worked only if quotes were used, e.g. listen="eth0.1").

Andrei Pelinescu-Onciul authored on 17/07/2009 13:37:11
Showing 2 changed files
... ...
@@ -112,6 +112,7 @@
112 112
 	int line=1;
113 113
 	int column=1;
114 114
 	int startcolumn=1;
115
+	char* yy_number_str=0; /* str correspondent for the current NUMBER token */
115 116
 
116 117
 	static char* addchar(struct str_buf *, char);
117 118
 	static char* addstr(struct str_buf *, char*, int);
... ...
@@ -403,6 +404,7 @@ LETTER		[a-zA-Z]
403 404
 DIGIT		[0-9]
404 405
 ALPHANUM	{LETTER}|{DIGIT}|[_]
405 406
 ID			{LETTER}{ALPHANUM}*
407
+NUM_ID		{ALPHANUM}+
406 408
 HEX			[0-9a-fA-F]
407 409
 HEXNUMBER	0x{HEX}+
408 410
 OCTNUMBER	0[0-7]+
... ...
@@ -784,10 +786,14 @@ EAT_ABLE	[\ \t\b\r]
784 786
 <SELECT>{DOT}           { count(); return DOT; }
785 787
 <SELECT>{LBRACK}        { count(); return LBRACK; }
786 788
 <SELECT>{RBRACK}        { count(); return RBRACK; }
787
-<SELECT>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);return NUMBER; }
788
-<SELECT>{HEXNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 16); return NUMBER; }
789
-<SELECT>{OCTNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 8); return NUMBER; }
790
-<SELECT>{BINNUMBER}     { count(); yylval.intval=(int)strtol(yytext, 0, 2); return NUMBER; }
789
+<SELECT>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);
790
+						yy_number_str=yytext; return NUMBER; }
791
+<SELECT>{HEXNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 16);
792
+						yy_number_str=yytext; return NUMBER; }
793
+<SELECT>{OCTNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 8);
794
+						yy_number_str=yytext; return NUMBER; }
795
+<SELECT>{BINNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 2);
796
+						yy_number_str=yytext; return NUMBER; }
791 797
 
792 798
 
793 799
 <INITIAL>{ATTR_MARK}    { count(); state = ATTR_S; BEGIN(ATTR); return ATTR_MARK; }
... ...
@@ -804,7 +810,8 @@ EAT_ABLE	[\ \t\b\r]
804 810
 <ATTR>{LBRACK}          { count(); return LBRACK; }
805 811
 <ATTR>{RBRACK}          { count(); return RBRACK; }
806 812
 <ATTR>{STAR}		{ count(); return STAR; }
807
-<ATTR>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);return NUMBER; }
813
+<ATTR>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);
814
+						yy_number_str=yytext; return NUMBER; }
808 815
 <ATTR>{ID}		{ count(); addstr(&s_buf, yytext, yyleng);
809 816
                            yylval.strval=s_buf.s;
810 817
 			   memset(&s_buf, 0, sizeof(s_buf));
... ...
@@ -814,26 +821,32 @@ EAT_ABLE	[\ \t\b\r]
814 821
                         }
815 822
 
816 823
 <INITIAL>{IPV6ADDR}		{ count(); yylval.strval=yytext; return IPV6ADDR; }
817
-<INITIAL>{DECNUMBER}		{ count(); yylval.intval=atoi(yytext);return NUMBER; }
824
+<INITIAL>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);
825
+								yy_number_str=yytext; return NUMBER; }
818 826
 <INITIAL>{HEXNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 16);
819
-							return NUMBER; }
827
+							yy_number_str=yytext; return NUMBER; }
820 828
 <INITIAL>{OCTNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 8);
821 829
 							return NUMBER; }
822
-<INITIAL>{BINNUMBER}    { count(); yylval.intval=(int)strtol(yytext, 0, 2); return NUMBER; }
823
-<INITIAL>{YES}			{ count(); yylval.intval=1; return NUMBER; }
824
-<INITIAL>{NO}			{ count(); yylval.intval=0; return NUMBER; }
830
+<INITIAL>{BINNUMBER}    { count(); yylval.intval=(int)strtol(yytext, 0, 2);
831
+							yy_number_str=yytext; return NUMBER; }
832
+<INITIAL>{YES}			{ count(); yylval.intval=1;
833
+							yy_number_str=yytext; return NUMBER; }
834
+<INITIAL>{NO}			{ count(); yylval.intval=0;
835
+							yy_number_str=yytext; return NUMBER; }
825 836
 <INITIAL>{TCP}			{ count(); return TCP; }
826 837
 <INITIAL>{UDP}			{ count(); return UDP; }
827 838
 <INITIAL>{TLS}			{ count(); return TLS; }
828 839
 <INITIAL>{SCTP}			{ count(); return SCTP; }
829
-<INITIAL>{INET}			{ count(); yylval.intval=AF_INET; return NUMBER; }
840
+<INITIAL>{INET}			{ count(); yylval.intval=AF_INET;
841
+							yy_number_str=yytext; return NUMBER; }
830 842
 <INITIAL>{INET6}		{ count();
831 843
 						#ifdef USE_IPV6
832 844
 						  yylval.intval=AF_INET6;
833 845
 						#else
834 846
 						  yylval.intval=-1; /* no match*/
835 847
 						#endif
836
-						  return NUMBER; }
848
+						yy_number_str=yytext;
849
+						return NUMBER; }
837 850
 <INITIAL>{SSLv23}		{ count(); yylval.strval=yytext; return SSLv23; }
838 851
 <INITIAL>{SSLv2}		{ count(); yylval.strval=yytext; return SSLv2; }
839 852
 <INITIAL>{SSLv3}		{ count(); yylval.strval=yytext; return SSLv3; }
... ...
@@ -907,6 +920,10 @@ EAT_ABLE	[\ \t\b\r]
907 920
 									yylval.strval=s_buf.s;
908 921
 									memset(&s_buf, 0, sizeof(s_buf));
909 922
 									return ID; }
923
+<INITIAL>{NUM_ID}			{ count(); addstr(&s_buf, yytext, yyleng);
924
+									yylval.strval=s_buf.s;
925
+									memset(&s_buf, 0, sizeof(s_buf));
926
+									return NUM_ID; }
910 927
 
911 928
 <SELECT>.               { unput(yytext[0]); state = INITIAL_S; BEGIN(INITIAL); } /* Rescan the token in INITIAL state */
912 929
 
... ...
@@ -180,6 +180,9 @@
180 180
 
181 181
 
182 182
 extern int yylex();
183
+/* safer then using yytext which can be array or pointer */
184
+extern char* yy_number_str;
185
+
183 186
 static void yyerror(char* s);
184 187
 static char* tmp;
185 188
 static int i_tmp;
... ...
@@ -477,6 +480,7 @@ static void free_socket_id_lst(struct socket_id* i);
477 480
 /* values */
478 481
 %token <intval> NUMBER
479 482
 %token <strval> ID
483
+%token <strval> NUM_ID
480 484
 %token <strval> STRING
481 485
 %token <strval> IPV6ADDR
482 486
 
... ...
@@ -501,7 +505,7 @@ static void free_socket_id_lst(struct socket_id* i);
501 505
 %type <action> action actions cmd fcmd if_cmd stm exp_stm assign_action
502 506
 %type <ipaddr> ipv4 ipv6 ipv6addr ip
503 507
 %type <ipnet> ipnet
504
-%type <strval> host
508
+%type <strval> host host_or_if host_if_id
505 509
 %type <strval> listen_id
506 510
 %type <name_l> listen_id_lst
507 511
 %type <name_l> listen_id2
... ...
@@ -582,7 +586,7 @@ listen_id:
582 586
 				strncpy($$, $1, strlen($1)+1);
583 587
 		}
584 588
 	}
585
-	| host {
589
+	| host_or_if {
586 590
 		if ($1){
587 591
 			$$=pkg_malloc(strlen($1)+1);
588 592
 			if ($$==0) {
... ...
@@ -1920,10 +1924,37 @@ host:
1920 1924
 			}
1921 1925
 			pkg_free($1);
1922 1926
 		}
1923
-		pkg_free($3);
1924 1927
 	}
1925 1928
 	| host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
1926 1929
 	;
1930
+
1931
+host_if_id: ID
1932
+		| NUM_ID
1933
+		| NUMBER { $$=yy_number_str /* text version */; }
1934
+		;
1935
+
1936
+host_or_if:
1937
+	host_if_id { $$=$1; }
1938
+	| host_or_if host_sep host_if_id {
1939
+		if ($1){
1940
+			$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1941
+			if ($$==0) {
1942
+				LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
1943
+							" failure while parsing host/interface name\n");
1944
+			} else {
1945
+				memcpy($$, $1, strlen($1));
1946
+				$$[strlen($1)]=*$2;
1947
+				memcpy($$+strlen($1)+1, $3, strlen($3));
1948
+				$$[strlen($1)+1+strlen($3)]=0;
1949
+			}
1950
+			pkg_free($1);
1951
+		}
1952
+	}
1953
+	| host_or_if host_sep error { $$=0; pkg_free($1);
1954
+								yyerror("invalid host or interface name"); }
1955
+	;
1956
+
1957
+
1927 1958
 /* filtered cmd */
1928 1959
 fcmd:
1929 1960
 	cmd {
... ...
@@ -2561,6 +2592,7 @@ func_param:
2561 2592
 extern int line;
2562 2593
 extern int column;
2563 2594
 extern int startcolumn;
2595
+
2564 2596
 static void warn(char* s)
2565 2597
 {
2566 2598
 	LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n", line, startcolumn,