Browse code

- myself matches now also the uri port - modified check_self, add_alias & grep_alias to accept port numbers - added loopback check - modified get_send_socket to return the first non loopback ipv4 interface if bind_address==0

Andrei Pelinescu-Onciul authored on 23/10/2002 15:12:20
Showing 11 changed files
... ...
@@ -71,7 +71,6 @@ int do_action(struct action* a, struct sip_msg* msg)
71 71
 	char *new_uri, *end, *crt;
72 72
 	int len;
73 73
 	int user;
74
-	int err;
75 74
 	struct sip_uri uri;
76 75
 	struct sip_uri* u;
77 76
 	unsigned short port;
... ...
@@ -100,19 +99,7 @@ int do_action(struct action* a, struct sip_msg* msg)
100 100
 				u=&msg->parsed_uri;
101 101
 				switch (a->p2_type){
102 102
 					case URIPORT_ST:
103
-									if (u->port.s){
104
-									 /*port=strtol(uri.port.s,&end,10);*/
105
-										port=str2s((unsigned char*)u->port.s,
106
-													u->port.len, &err);
107
-										/*if ((end)&&(*end)){*/
108
-										if (err){
109
-											LOG(L_ERR, "ERROR: do_action: "
110
-												"forward: bad port in "
111
-												"uri: <%s>\n", u->port.s);
112
-											ret=E_BAD_URI;
113
-											goto error_fwd_uri;
114
-										}
115
-									}else port=0;
103
+									port=u->port_no;
116 104
 									break;
117 105
 					case NUMBER_ST:
118 106
 									port=a->p2.number;
... ...
@@ -315,8 +315,8 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
315 315
 		| LISTEN EQUAL  error { yyerror("ip address or hostname"
316 316
 						"expected"); }
317 317
 		| ALIAS EQUAL  id_lst { 
318
-								for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
319
-									add_alias(lst_tmp->s, strlen(lst_tmp->s));
318
+							for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
319
+								add_alias(lst_tmp->s, strlen(lst_tmp->s), 0);
320 320
 							  }
321 321
 		| ALIAS  EQUAL error  { yyerror(" hostname expected"); }
322 322
 		| error EQUAL { yyerror("unknown config variable"); }
... ...
@@ -70,7 +70,7 @@ struct socket_info* get_send_socket(union sockaddr_union* to)
70 70
 	send_sock=0;
71 71
 	/* check if we need to change the socket (different address families -
72 72
 	 * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
73
-	if (to->s.sa_family!=bind_address->address.af){
73
+	if ((bind_address==0) ||(to->s.sa_family!=bind_address->address.af)){
74 74
 		switch(to->s.sa_family){
75 75
 			case AF_INET:	send_sock=sendipv4;
76 76
 							break;
... ...
@@ -87,10 +87,11 @@ struct socket_info* get_send_socket(union sockaddr_union* to)
87 87
 
88 88
 
89 89
 
90
-/* checks if the host is one of the address we listen on
91
-* returns 1 if true, 0 if false, -1 on error
90
+/* checks if the host:port is one of the address we listen on;
91
+ * if port==0, the  port number is ignored
92
+ * returns 1 if true, 0 if false, -1 on error
92 93
 */
93
-int check_self(str* host)
94
+int check_self(str* host, unsigned short port)
94 95
 {
95 96
 	int r;
96 97
 	
... ...
@@ -102,6 +103,7 @@ int check_self(str* host)
102 102
 					host->len, host->s,
103 103
 					sock_info[r].name.len, sock_info[r].name.s
104 104
 			);
105
+		if  ((port)&&(sock_info[r].port_no!=port)) continue;
105 106
 		if ( (host->len==sock_info[r].name.len) && 
106 107
 	#ifdef USE_IPV6
107 108
 			(strncasecmp(host->s, sock_info[r].name.s,
... ...
@@ -127,7 +129,7 @@ int check_self(str* host)
127 127
 	}
128 128
 	if (r==sock_no){
129 129
 		/* try to look into the aliases*/
130
-		if (grep_aliases(host->s, host->len)==0){
130
+		if (grep_aliases(host->s, host->len, port)==0){
131 131
 			DBG("check_self: host != me\n");
132 132
 			return 0;
133 133
 		}
... ...
@@ -312,9 +314,11 @@ int forward_reply(struct sip_msg* msg)
312 312
 	new_buf=0;
313 313
 	/*check if first via host = us */
314 314
 	if (check_via){
315
-		if (check_self(&(msg->via1->host))!=1){
315
+		if (check_self(&msg->via1->host,
316
+					msg->via1->port?msg->via1->port:SIP_PORT)!=1){
316 317
 			LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
317
-					" %.*s\n", msg->via1->host.len, msg->via1->host.s);
318
+					" %.*s:%d\n", msg->via1->host.len, msg->via1->host.s
319
+									msg->via1->port);
318 320
 			/* send error msg back? */
319 321
 			goto error;
320 322
 		}
... ...
@@ -367,7 +371,7 @@ int forward_reply(struct sip_msg* msg)
367 367
 #endif
368 368
 	}
369 369
 
370
-	DBG(" reply forwarded to %s:%d\n",msg->via2->host.s,
370
+	DBG(" reply forwarded to %s:%d\n", msg->via2->host.s,
371 371
 		(unsigned short) msg->via2->port);
372 372
 
373 373
 	pkg_free(new_buf);
... ...
@@ -37,7 +37,7 @@
37 37
 
38 38
 
39 39
 struct socket_info* get_send_socket(union sockaddr_union* su);
40
-int check_self(str* host);
40
+int check_self(str* host, unsigned short port);
41 41
 int forward_request( struct sip_msg* msg,  struct proxy_l* p);
42 42
 int update_sock_struct_from_via( union sockaddr_union* to,
43 43
 								struct via_body* via );
... ...
@@ -78,6 +78,7 @@ struct socket_info{
78 78
 	unsigned short port_no;  /* port number */
79 79
 	str port_no_str; /* port number converted to string -- optimization*/
80 80
 	int is_ip; /* 1 if name is an ip address, 0 if not  -- optimization*/
81
+	int is_lo; /* 1 if is a loopback, 0 if not */
81 82
 	union sockaddr_union su; 
82 83
 };
83 84
 
... ...
@@ -266,7 +266,7 @@ int addresses_no=0;                   /* number of names/ips */
266 266
 #endif
267 267
 struct socket_info sock_info[MAX_LISTEN];/*all addresses we listen/send from*/
268 268
 int sock_no=0; /* number of addresses/open sockets*/
269
-struct socket_info* bind_address; /* pointer to the crt. proc.
269
+struct socket_info* bind_address=0; /* pointer to the crt. proc.
270 270
 									 listening address*/
271 271
 int bind_idx; /* same as above but index in the bound[] array */
272 272
 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
... ...
@@ -588,7 +588,8 @@ int main_loop()
588 588
 			/* create the listening socket (for each address)*/
589 589
 			if (udp_init(&sock_info[r])==-1) goto error;
590 590
 			/* get first ipv4/ipv6 socket*/
591
-			if ((sendipv4==0)&&(sock_info[r].address.af==AF_INET))
591
+			if ((sock_info[r].address.af==AF_INET)&&
592
+					((sendipv4==0)||(sendipv4->is_lo)))
592 593
 				sendipv4=&sock_info[r];
593 594
 	#ifdef USE_IPV6
594 595
 			if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6))
... ...
@@ -803,10 +804,11 @@ int add_interfaces(char* if_name, int family, unsigned short port)
803 803
 			continue;
804 804
 		}
805 805
 		
806
-		if (if_name==0){ /* ignore down ifs only if listening on all of them*/
807
-			memcpy(&ifrcopy, ifr, sizeof(ifrcopy));
808
-			/*get flags*/
809
-			if (ioctl(s, SIOCGIFFLAGS,  &ifrcopy)!=-1){ /* ignore errors */
806
+		/*get flags*/
807
+		memcpy(&ifrcopy, ifr, sizeof(ifrcopy));
808
+		if (ioctl(s, SIOCGIFFLAGS,  &ifrcopy)!=-1){ /* ignore errors */
809
+			/* ignore down ifs only if listening on all of them*/
810
+			if (if_name==0){ 
810 811
 				/* if if not up, skip it*/
811 812
 				if (!(ifrcopy.ifr_flags & IFF_UP)) continue;
812 813
 			}
... ...
@@ -832,6 +834,9 @@ int add_interfaces(char* if_name, int family, unsigned short port)
832 832
 				strncpy(sock_info[sock_no].name.s, tmp, 
833 833
 							sock_info[sock_no].name.len+1);
834 834
 				sock_info[sock_no].port_no=port;
835
+				/* mark if loopback */
836
+				if (ifrcopy.ifr_flags & IFF_LOOPBACK) 
837
+					sock_info[sock_no].is_lo=1;
835 838
 				sock_no++;
836 839
 				ret=0;
837 840
 			}else{
... ...
@@ -1194,6 +1199,29 @@ int main(int argc, char** argv)
1194 1194
 	printf("Listening on \n");
1195 1195
 #endif
1196 1196
 	for (r=0; r<sock_no;r++){
1197
+		/* fix port number, port_no should be !=0 here */
1198
+		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
1199
+		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
1200
+									(unsigned short) sock_info[r].port_no);
1201
+		if (port_no_str_len<0){
1202
+			fprintf(stderr, "ERROR: bad port number: %d\n", 
1203
+						sock_info[r].port_no);
1204
+			goto error;
1205
+		}
1206
+		/* on some systems snprintf returns really strange things if it does 
1207
+		  not have  enough space */
1208
+		port_no_str_len=
1209
+				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
1210
+		sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1);
1211
+		if (sock_info[r].port_no_str.s==0){
1212
+			fprintf(stderr, "Out of memory.\n");
1213
+			goto error;
1214
+		}
1215
+		strncpy(sock_info[r].port_no_str.s, port_no_str,
1216
+					strlen(port_no_str)+1);
1217
+		sock_info[r].port_no_str.len=strlen(port_no_str);
1218
+		
1219
+		/* get "official hostnames", all the aliases etc. */
1197 1220
 		he=resolvehost(sock_info[r].name.s);
1198 1221
 		if (he==0){
1199 1222
 			DPrint("ERROR: could not resolve %s\n", sock_info[r].name.s);
... ...
@@ -1201,7 +1229,8 @@ int main(int argc, char** argv)
1201 1201
 		}
1202 1202
 		/* check if we got the official name */
1203 1203
 		if (strcasecmp(he->h_name, sock_info[r].name.s)!=0){
1204
-			if (add_alias(sock_info[r].name.s, sock_info[r].name.len)<0){
1204
+			if (add_alias(sock_info[r].name.s, sock_info[r].name.len,
1205
+							sock_info[r].port_no)<0){
1205 1206
 				LOG(L_ERR, "ERROR: main: add_alias failed\n");
1206 1207
 			}
1207 1208
 			/* change the oficial name */
... ...
@@ -1216,7 +1245,7 @@ int main(int argc, char** argv)
1216 1216
 		}
1217 1217
 		/* add the aliases*/
1218 1218
 		for(h=he->h_aliases; h && *h; h++)
1219
-			if (add_alias(*h, strlen(*h))<0){
1219
+			if (add_alias(*h, strlen(*h), sock_info[r].port_no)<0){
1220 1220
 				LOG(L_ERR, "ERROR: main: add_alias failed\n");
1221 1221
 			}
1222 1222
 		hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr 
... ...
@@ -1242,36 +1271,17 @@ int main(int argc, char** argv)
1242 1242
 							sock_info[r].name.s);
1243 1243
 				}else{
1244 1244
 					/* add the aliases*/
1245
-					if (add_alias(he->h_name, strlen(he->h_name))<0){
1245
+					if (add_alias(he->h_name, strlen(he->h_name),
1246
+									sock_info[r].port_no)<0){
1246 1247
 						LOG(L_ERR, "ERROR: main: add_alias failed\n");
1247 1248
 					}
1248 1249
 					for(h=he->h_aliases; h && *h; h++)
1249
-						if (add_alias(*h, strlen(*h))<0){
1250
+						if (add_alias(*h,strlen(*h),sock_info[r].port_no)<0){
1250 1251
 							LOG(L_ERR, "ERROR: main: add_alias failed\n");
1251 1252
 						}
1252 1253
 				}
1253 1254
 		}else{ sock_info[r].is_ip=0; };
1254 1255
 			
1255
-		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
1256
-		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
1257
-									(unsigned short) sock_info[r].port_no);
1258
-		if (port_no_str_len<0){
1259
-			fprintf(stderr, "ERROR: bad port number: %d\n", 
1260
-						sock_info[r].port_no);
1261
-			goto error;
1262
-		}
1263
-		/* on some systems snprintf returns really strange things if it does 
1264
-		  not have  enough space */
1265
-		port_no_str_len=
1266
-				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
1267
-		sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1);
1268
-		if (sock_info[r].port_no_str.s==0){
1269
-			fprintf(stderr, "Out of memory.\n");
1270
-			goto error;
1271
-		}
1272
-		strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1);
1273
-		sock_info[r].port_no_str.len=strlen(port_no_str);
1274
-		
1275 1256
 #ifdef EXTRA_DEBUG
1276 1257
 		printf("              %.*s [%s]:%s\n", sock_info[r].name.len, 
1277 1258
 				sock_info[r].name.s,
... ...
@@ -1298,7 +1308,8 @@ int main(int argc, char** argv)
1298 1298
 						(strncmp(sock_info[t].name.s, sock_info[r].name.s,
1299 1299
 								 sock_info[r].name.len)!=0))
1300 1300
 					)
1301
-					add_alias(sock_info[t].name.s, sock_info[t].name.len);
1301
+					add_alias(sock_info[t].name.s, sock_info[t].name.len,
1302
+								sock_info[t].port_no);
1302 1303
 						
1303 1304
 				/* free space*/
1304 1305
 				free(sock_info[t].name.s);
... ...
@@ -1320,7 +1331,11 @@ int main(int argc, char** argv)
1320 1320
 				sock_info[r].address_str.s, sock_info[r].port_no_str.s);
1321 1321
 
1322 1322
 	printf("Aliases: ");
1323
-	for(a=aliases; a; a=a->next) printf("%.*s ", a->alias.len, a->alias.s);
1323
+	for(a=aliases; a; a=a->next) 
1324
+		if (a->port)
1325
+			printf("%.*s:%d ", a->alias.len, a->alias.s, a->port);
1326
+		else
1327
+			printf("%.*s:* ", a->alias.len, a->alias.s);
1324 1328
 	printf("\n");
1325 1329
 	if (sock_no==0){
1326 1330
 		fprintf(stderr, "ERROR: no listening sockets");
... ...
@@ -35,6 +35,7 @@
35 35
 
36 36
 struct host_alias{
37 37
 	str alias;
38
+	unsigned short port;
38 39
 	struct host_alias* next;
39 40
 };
40 41
 
... ...
@@ -43,13 +44,14 @@ extern struct host_alias* aliases;
43 43
 
44 44
 
45 45
 
46
-/* returns 1 if  name is in the alias list*/
47
-static inline int grep_aliases(char* name, int len)
46
+/* returns 1 if  name is in the alias list; if port=0, port no is ignored*/
47
+static inline int grep_aliases(char* name, int len, unsigned short port)
48 48
 {
49 49
 	struct  host_alias* a;
50 50
 	
51 51
 	for(a=aliases;a;a=a->next)
52
-		if ((a->alias.len==len) && (strncasecmp(a->alias.s, name, len)==0))
52
+		if ((a->alias.len==len) && ((a->port==0) || (port==0) || 
53
+				(a->port==port)) && (strncasecmp(a->alias.s, name, len)==0))
53 54
 			return 1;
54 55
 	return 0;
55 56
 }
... ...
@@ -57,13 +59,14 @@ static inline int grep_aliases(char* name, int len)
57 57
 
58 58
 
59 59
 /* adds an alias to the list (only if it isn't already there)
60
+ * if port==0, the alias will match all the ports
60 61
  * returns 1 if a new alias was added, 0 if the alias was already on the list
61 62
  * and  -1 on error */
62
-static inline int add_alias(char* name, int len)
63
+static inline int add_alias(char* name, int len, unsigned short port)
63 64
 {
64 65
 	struct host_alias* a;
65 66
 	
66
-	if (grep_aliases(name,len)) return 0;
67
+	if ((port) && grep_aliases(name,len, port)) return 0;
67 68
 	a=0;
68 69
 	a=(struct host_alias*)malloc(sizeof(struct host_alias));
69 70
 	if(a==0) goto error;
... ...
@@ -72,6 +75,7 @@ static inline int add_alias(char* name, int len)
72 72
 	a->alias.len=len;
73 73
 	memcpy(a->alias.s, name, len);
74 74
 	a->alias.s[len]=0; /* null terminate for easier printing*/
75
+	a->port=port;
75 76
 	a->next=aliases;
76 77
 	aliases=a;
77 78
 	return 1;
... ...
@@ -72,6 +72,7 @@ struct sip_uri {
72 72
 	str port;     /* Port number */
73 73
 	str params;   /* Parameters */
74 74
 	str headers;  
75
+	unsigned short port_no;
75 76
 };
76 77
 
77 78
 
... ...
@@ -42,6 +42,7 @@ int parse_uri(char *buf, int len, struct sip_uri* uri)
42 42
 	char* next, *end;
43 43
 	char *user, *passwd, *host, *port, *params, *headers, *ipv6;
44 44
 	int host_len, port_len, params_len, headers_len;
45
+	int err;
45 46
 	int ret;
46 47
 	
47 48
 	
... ...
@@ -208,7 +209,15 @@ int parse_uri(char *buf, int len, struct sip_uri* uri)
208 208
 		uri->headers.len=headers_len;
209 209
 		uri->headers.s[headers_len]=0;
210 210
 	}else uri->headers.s=0;
211
-	
211
+
212
+	err=0;
213
+	if (uri->port.s) uri->port_no=str2s(uri->port.s, uri->port.len, &err);
214
+	if (err){
215
+		LOG(L_DBG, "ERROR: parse_uri: bad port number in sip uri: %s\n",
216
+				uri->port.s);
217
+		ser_error=ret=E_BAD_URI;
218
+		goto error;
219
+	}
212 220
 	return ret;
213 221
 error:
214 222
 	free_uri(uri);
... ...
@@ -262,7 +262,7 @@ error:
262 262
 
263 263
 
264 264
 
265
-/* eval_elem helping function, returns a op param */
265
+/* eval_elem helping function, returns an op param */
266 266
 static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
267 267
 {
268 268
 	struct hostent* he;
... ...
@@ -305,7 +305,7 @@ static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
305 305
 		case MYSELF_ST: /* check if it's one of our addresses*/
306 306
 			tmp.s=ip_addr2a(ip);
307 307
 			tmp.len=strlen(tmp.s);
308
-			ret=check_self(&tmp);
308
+			ret=check_self(&tmp, 0);
309 309
 			break;
310 310
 		default:
311 311
 			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
... ...
@@ -338,7 +338,9 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
338 338
 				if(msg->new_uri.s){
339 339
 					if (e->subtype==MYSELF_ST){
340 340
 						if (parse_sip_msg_uri(msg)<0) ret=-1;
341
-						else	ret=check_self(&msg->parsed_uri.host);
341
+						else	ret=check_self(&msg->parsed_uri.host,
342
+									msg->parsed_uri.port_no?
343
+									msg->parsed_uri.port_no:SIP_PORT);
342 344
 					}else{
343 345
 						ret=comp_str(msg->new_uri.s, e->r.param,
344 346
 										e->op, e->subtype);
... ...
@@ -346,7 +348,9 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
346 346
 				}else{
347 347
 					if (e->subtype==MYSELF_ST){
348 348
 						if (parse_sip_msg_uri(msg)<0) ret=-1;
349
-						else	ret=check_self(&msg->parsed_uri.host);
349
+						else	ret=check_self(&msg->parsed_uri.host,
350
+									msg->parsed_uri.port_no?
351
+									msg->parsed_uri.port_no:SIP_PORT);
350 352
 					}else{
351 353
 						ret=comp_str(msg->first_line.u.request.uri.s,
352 354
 										 e->r.param, e->op, e->subtype);
... ...
@@ -6,6 +6,8 @@ rev_dns=off
6 6
 log_stderror=yes
7 7
 #children=8
8 8
 fifo=""
9
+alias=foo.bar
10
+alias=testing
9 11
 
10 12
 route{
11 13