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 403
 DIGIT		[0-9]
404 404
 ALPHANUM	{LETTER}|{DIGIT}|[_]
405 405
 ID			{LETTER}{ALPHANUM}*
406
+NUM_ID		{ALPHANUM}+
406 407
 HEX			[0-9a-fA-F]
407 408
 HEXNUMBER	0x{HEX}+
408 409
 OCTNUMBER	0[0-7]+
... ...
@@ -784,10 +786,14 @@ EAT_ABLE	[\ \t\b\r]
784 784
 <SELECT>{DOT}           { count(); return DOT; }
785 785
 <SELECT>{LBRACK}        { count(); return LBRACK; }
786 786
 <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; }
787
+<SELECT>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);
788
+						yy_number_str=yytext; return NUMBER; }
789
+<SELECT>{HEXNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 16);
790
+						yy_number_str=yytext; return NUMBER; }
791
+<SELECT>{OCTNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 8);
792
+						yy_number_str=yytext; return NUMBER; }
793
+<SELECT>{BINNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 2);
794
+						yy_number_str=yytext; return NUMBER; }
791 795
 
792 796
 
793 797
 <INITIAL>{ATTR_MARK}    { count(); state = ATTR_S; BEGIN(ATTR); return ATTR_MARK; }
... ...
@@ -804,7 +810,8 @@ EAT_ABLE	[\ \t\b\r]
804 804
 <ATTR>{LBRACK}          { count(); return LBRACK; }
805 805
 <ATTR>{RBRACK}          { count(); return RBRACK; }
806 806
 <ATTR>{STAR}		{ count(); return STAR; }
807
-<ATTR>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);return NUMBER; }
807
+<ATTR>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);
808
+						yy_number_str=yytext; return NUMBER; }
808 809
 <ATTR>{ID}		{ count(); addstr(&s_buf, yytext, yyleng);
809 810
                            yylval.strval=s_buf.s;
810 811
 			   memset(&s_buf, 0, sizeof(s_buf));
... ...
@@ -814,26 +821,32 @@ EAT_ABLE	[\ \t\b\r]
814 814
                         }
815 815
 
816 816
 <INITIAL>{IPV6ADDR}		{ count(); yylval.strval=yytext; return IPV6ADDR; }
817
-<INITIAL>{DECNUMBER}		{ count(); yylval.intval=atoi(yytext);return NUMBER; }
817
+<INITIAL>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);
818
+								yy_number_str=yytext; return NUMBER; }
818 819
 <INITIAL>{HEXNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 16);
819
-							return NUMBER; }
820
+							yy_number_str=yytext; return NUMBER; }
820 821
 <INITIAL>{OCTNUMBER}	{ count(); yylval.intval=(int)strtol(yytext, 0, 8);
821 822
 							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; }
823
+<INITIAL>{BINNUMBER}    { count(); yylval.intval=(int)strtol(yytext, 0, 2);
824
+							yy_number_str=yytext; return NUMBER; }
825
+<INITIAL>{YES}			{ count(); yylval.intval=1;
826
+							yy_number_str=yytext; return NUMBER; }
827
+<INITIAL>{NO}			{ count(); yylval.intval=0;
828
+							yy_number_str=yytext; return NUMBER; }
825 829
 <INITIAL>{TCP}			{ count(); return TCP; }
826 830
 <INITIAL>{UDP}			{ count(); return UDP; }
827 831
 <INITIAL>{TLS}			{ count(); return TLS; }
828 832
 <INITIAL>{SCTP}			{ count(); return SCTP; }
829
-<INITIAL>{INET}			{ count(); yylval.intval=AF_INET; return NUMBER; }
833
+<INITIAL>{INET}			{ count(); yylval.intval=AF_INET;
834
+							yy_number_str=yytext; return NUMBER; }
830 835
 <INITIAL>{INET6}		{ count();
831 836
 						#ifdef USE_IPV6
832 837
 						  yylval.intval=AF_INET6;
833 838
 						#else
834 839
 						  yylval.intval=-1; /* no match*/
835 840
 						#endif
836
-						  return NUMBER; }
841
+						yy_number_str=yytext;
842
+						return NUMBER; }
837 843
 <INITIAL>{SSLv23}		{ count(); yylval.strval=yytext; return SSLv23; }
838 844
 <INITIAL>{SSLv2}		{ count(); yylval.strval=yytext; return SSLv2; }
839 845
 <INITIAL>{SSLv3}		{ count(); yylval.strval=yytext; return SSLv3; }
... ...
@@ -907,6 +920,10 @@ EAT_ABLE	[\ \t\b\r]
907 907
 									yylval.strval=s_buf.s;
908 908
 									memset(&s_buf, 0, sizeof(s_buf));
909 909
 									return ID; }
910
+<INITIAL>{NUM_ID}			{ count(); addstr(&s_buf, yytext, yyleng);
911
+									yylval.strval=s_buf.s;
912
+									memset(&s_buf, 0, sizeof(s_buf));
913
+									return NUM_ID; }
910 914
 
911 915
 <SELECT>.               { unput(yytext[0]); state = INITIAL_S; BEGIN(INITIAL); } /* Rescan the token in INITIAL state */
912 916
 
... ...
@@ -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 477
 /* values */
478 478
 %token <intval> NUMBER
479 479
 %token <strval> ID
480
+%token <strval> NUM_ID
480 481
 %token <strval> STRING
481 482
 %token <strval> IPV6ADDR
482 483
 
... ...
@@ -501,7 +505,7 @@ static void free_socket_id_lst(struct socket_id* i);
501 501
 %type <action> action actions cmd fcmd if_cmd stm exp_stm assign_action
502 502
 %type <ipaddr> ipv4 ipv6 ipv6addr ip
503 503
 %type <ipnet> ipnet
504
-%type <strval> host
504
+%type <strval> host host_or_if host_if_id
505 505
 %type <strval> listen_id
506 506
 %type <name_l> listen_id_lst
507 507
 %type <name_l> listen_id2
... ...
@@ -582,7 +586,7 @@ listen_id:
582 582
 				strncpy($$, $1, strlen($1)+1);
583 583
 		}
584 584
 	}
585
-	| host {
585
+	| host_or_if {
586 586
 		if ($1){
587 587
 			$$=pkg_malloc(strlen($1)+1);
588 588
 			if ($$==0) {
... ...
@@ -1920,10 +1924,37 @@ host:
1920 1920
 			}
1921 1921
 			pkg_free($1);
1922 1922
 		}
1923
-		pkg_free($3);
1924 1923
 	}
1925 1924
 	| host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
1926 1925
 	;
1926
+
1927
+host_if_id: ID
1928
+		| NUM_ID
1929
+		| NUMBER { $$=yy_number_str /* text version */; }
1930
+		;
1931
+
1932
+host_or_if:
1933
+	host_if_id { $$=$1; }
1934
+	| host_or_if host_sep host_if_id {
1935
+		if ($1){
1936
+			$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1937
+			if ($$==0) {
1938
+				LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
1939
+							" failure while parsing host/interface name\n");
1940
+			} else {
1941
+				memcpy($$, $1, strlen($1));
1942
+				$$[strlen($1)]=*$2;
1943
+				memcpy($$+strlen($1)+1, $3, strlen($3));
1944
+				$$[strlen($1)+1+strlen($3)]=0;
1945
+			}
1946
+			pkg_free($1);
1947
+		}
1948
+	}
1949
+	| host_or_if host_sep error { $$=0; pkg_free($1);
1950
+								yyerror("invalid host or interface name"); }
1951
+	;
1952
+
1953
+
1927 1954
 /* filtered cmd */
1928 1955
 fcmd:
1929 1956
 	cmd {
... ...
@@ -2561,6 +2592,7 @@ func_param:
2561 2561
 extern int line;
2562 2562
 extern int column;
2563 2563
 extern int startcolumn;
2564
+
2564 2565
 static void warn(char* s)
2565 2566
 {
2566 2567
 	LOG(L_WARN, "cfg. warning: (%d,%d-%d): %s\n", line, startcolumn,