浏览代码

- added myself==src_ip/dst_ip/uri condition
- created parse_sip_msg_uri which puts the result in msg->parsed_uri & updates
msg->parsed_rui_ok
- changed default value of syn_branch to 1

Andrei Pelinescu-Onciul 23 年之前
父节点
当前提交
855c2e68ee
共有 16 个文件被更改,包括 186 次插入58 次删除
  1. 3 2
      Makefile.defs
  2. 25 17
      action.c
  3. 2 0
      cfg.lex
  4. 22 0
      cfg.y
  5. 47 22
      forward.c
  6. 1 0
      forward.h
  7. 1 0
      ip_addr.h
  8. 8 2
      main.c
  9. 2 0
      parser/msg_parser.c
  10. 14 1
      parser/msg_parser.h
  11. 27 0
      parser/parse_uri.c
  12. 2 8
      parser/parse_uri.h
  13. 22 4
      route.c
  14. 3 0
      route_struct.c
  15. 2 1
      route_struct.h
  16. 5 1
      test/stateless.cfg

+ 3 - 2
Makefile.defs

@@ -8,7 +8,7 @@
 VERSION = 0
 PATCHLEVEL = 8
 SUBLEVEL = 7
-EXTRAVERSION = -8-srv
+EXTRAVERSION = -9-self
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s)
@@ -99,7 +99,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
 	 -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
 	 -DUSE_IPV6 \
 	 -DEXTRA_DEBUG \
-	 -DVQ_MALLOC  -DDBG_QM_MALLOC \
+	 -DDBG_QM_MALLOC \
+	 #-DVQ_MALLOC  
 	 #-DCONTACT_BUG
 	 #-DF_MALLOC \
 	 #-DDBG_LOCK

+ 25 - 17
action.c

@@ -13,6 +13,7 @@
 #include "udp_server.h"
 #include "route.h"
 #include "parser/msg_parser.h"
+#include "parser/parse_uri.h"
 #include "ut.h"
 #include "sr_module.h"
 #include "mem/mem.h"
@@ -48,6 +49,7 @@ int do_action(struct action* a, struct sip_msg* msg)
 	int user;
 	int err;
 	struct sip_uri uri;
+	struct sip_uri* u;
 	unsigned short port;
 
 	/* reset the value of error to E_UNSPEC so avoid unknowledgable
@@ -65,30 +67,24 @@ int do_action(struct action* a, struct sip_msg* msg)
 		case FORWARD_T:
 			if (a->p1_type==URIHOST_ST){
 				/*parse uri*/
-				if (msg->new_uri.s){
-						tmp=msg->new_uri.s;
-						len=msg->new_uri.len;
-				}else{
-						tmp=msg->first_line.u.request.uri.s;
-						len=msg->first_line.u.request.uri.len;
-				}
-				ret=parse_uri(tmp, len, &uri );
+				ret=parse_sip_msg_uri(msg);
 				if (ret<0) {
-					LOG(L_ERR, "ERROR: do_action: forward: bad_uri <%s>,"
-								" dropping packet\n",tmp);
+					LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
+								" dropping packet\n");
 					break;
 				}
+				u=&msg->parsed_uri;
 				switch (a->p2_type){
 					case URIPORT_ST:
-									if (uri.port.s){
+									if (u->port.s){
 									 /*port=strtol(uri.port.s,&end,10);*/
-										port=str2s((unsigned char*)uri.port.s, 
-													uri.port.len, &err);
+										port=str2s((unsigned char*)u->port.s,
+													u->port.len, &err);
 										/*if ((end)&&(*end)){*/
 										if (err){
 											LOG(L_ERR, "ERROR: do_action: "
 												"forward: bad port in "
-												"uri: <%s>\n", uri.port.s);
+												"uri: <%s>\n", u->port.s);
 											ret=E_BAD_URI;
 											goto error_fwd_uri;
 										}
@@ -104,7 +100,7 @@ int do_action(struct action* a, struct sip_msg* msg)
 							goto error_fwd_uri;
 				}
 				/* create a temporary proxy*/
-				p=mk_proxy(uri.host.s, port);
+				p=mk_proxy(u->host.s, port);
 				if (p==0){
 					LOG(L_ERR, "ERROR:  bad host name in uri,"
 							" dropping packet\n");
@@ -112,7 +108,7 @@ int do_action(struct action* a, struct sip_msg* msg)
 					goto error_fwd_uri;
 				}
 				ret=forward_request(msg, p);
-				free_uri(&uri);
+				/*free_uri(&uri); -- no longer needed, in sip_msg*/
 				free_proxy(p); /* frees only p content, not p itself */
 				free(p);
 				if (ret>=0) ret=1;
@@ -299,6 +295,10 @@ int do_action(struct action* a, struct sip_msg* msg)
 				pkg_free(msg->new_uri.s);
 				msg->new_uri.len=0;
 				msg->new_uri.s=0;
+				if (msg->parsed_uri_ok){
+					msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
+					free_uri(&msg->parsed_uri);
+				}
 			};
 			ret=1;
 			break;
@@ -327,6 +327,10 @@ int do_action(struct action* a, struct sip_msg* msg)
 					if (msg->new_uri.s) {
 							pkg_free(msg->new_uri.s);
 							msg->new_uri.len=0;
+							if (msg->parsed_uri_ok){
+								msg->parsed_uri_ok=0;
+								free_uri(&msg->parsed_uri);
+							}
 					}
 					len=strlen(a->p1.string);
 					msg->new_uri.s=pkg_malloc(len+1);
@@ -460,6 +464,10 @@ int do_action(struct action* a, struct sip_msg* msg)
 				if (msg->new_uri.s) pkg_free(msg->new_uri.s);
 				msg->new_uri.s=new_uri;
 				msg->new_uri.len=crt-new_uri;
+				if (msg->parsed_uri_ok){
+					msg->parsed_uri_ok=0;
+					free_uri(&msg->parsed_uri);
+				}
 				free_uri(&uri);
 				ret=1;
 				break;
@@ -508,7 +516,7 @@ error_uri:
 	if (new_uri) free(new_uri);
 	return E_UNSPEC;
 error_fwd_uri:
-	free_uri(&uri);
+	/*free_uri(&uri); -- not needed anymore, using msg->parsed_uri*/
 	return ret;
 }
 

+ 2 - 0
cfg.lex

@@ -77,6 +77,7 @@ METHOD	method
 URI		uri
 SRCIP	src_ip
 DSTIP	dst_ip
+MYSELF	myself
 /* operators */
 EQUAL	=
 EQUAL_T	==
@@ -180,6 +181,7 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{URI}	{ count(); yylval.strval=yytext; return URI; }
 <INITIAL>{SRCIP}	{ count(); yylval.strval=yytext; return SRCIP; }
 <INITIAL>{DSTIP}	{ count(); yylval.strval=yytext; return DSTIP; }
+<INITIAL>{MYSELF}	{ count(); yylval.strval=yytext; return MYSELF; }
 
 <INITIAL>{DEBUG}	{ count(); yylval.strval=yytext; return DEBUG; }
 <INITIAL>{FORK}		{ count(); yylval.strval=yytext; return FORK; }

+ 22 - 0
cfg.y

@@ -81,6 +81,7 @@ void* f_tmp;
 %token URI
 %token SRCIP
 %token DSTIP
+%token MYSELF
 
 /* config vars. */
 %token DEBUG
@@ -427,6 +428,9 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
 		| URI EQUAL_T ID 	{$$ = mk_elem(	EQUAL_OP, STRING_ST,
 											URI_O, $3); 
 				 			}
+		| URI EQUAL_T MYSELF    { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
+												URI_O, 0);
+								}
 		| URI EQUAL_T error { $$=0; yyerror("string expected"); }
 		| URI MATCH STRING	{ $$=mk_elem(	MATCH_OP, STRING_ST,
 											URI_O, $3);
@@ -447,6 +451,9 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
 		| SRCIP EQUAL_T host	{ $$=mk_elem(	EQUAL_OP, STRING_ST,
 												SRCIP_O, $3);
 								}
+		| SRCIP EQUAL_T MYSELF  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
+												SRCIP_O, 0);
+								}
 		| SRCIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
 						 "expected" ); }
 		| SRCIP MATCH STRING	{ $$=mk_elem(	MATCH_OP, STRING_ST,
@@ -467,6 +474,9 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
 		| DSTIP EQUAL_T host	{ $$=mk_elem(	EQUAL_OP, STRING_ST,
 												DSTIP_O, $3);
 								}
+		| DSTIP EQUAL_T MYSELF  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
+												DSTIP_O, 0);
+								}
 		| DSTIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
 						 			"expected" ); }
 		| DSTIP MATCH STRING	{ $$=mk_elem(	MATCH_OP, STRING_ST,
@@ -478,6 +488,18 @@ exp_elem:	METHOD EQUAL_T STRING	{$$= mk_elem(	EQUAL_OP, STRING_ST,
 		| DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
 		| DSTIP error { $$=0; 
 						yyerror("invalid operator, == or =~ expected");}
+		| MYSELF EQUAL_T URI    { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
+												URI_O, 0);
+								}
+		| MYSELF EQUAL_T SRCIP  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
+												SRCIP_O, 0);
+								}
+		| MYSELF EQUAL_T DSTIP  { $$=mk_elem(	EQUAL_OP, MYSELF_ST,
+												DSTIP_O, 0);
+								}
+		| MYSELF EQUAL_T error {	$$=0; 
+									yyerror(" URI, SRCIP or DSTIP expected"); }
+		| MYSELF error	{ $$=0; yyerror ("invalid operator, == expected"); }
 		| stm				{ $$=mk_elem( NO_OP, ACTIONS_ST, ACTION_O, $1 ); }
 		| NUMBER		{$$=mk_elem( NO_OP, NUMBER_ST, NUMBER_O, (void*)$1 ); }
 	;

+ 47 - 22
forward.c

@@ -62,6 +62,52 @@ struct socket_info* get_send_socket(union sockaddr_union* to)
 
 
 
+/* checks if the host is one of the address we listen on
+* returns 1 if true, 0 if false, -1 on error
+*/
+int check_self(str* host)
+{
+	int r;
+	
+	for (r=0; r<sock_no; r++){
+		DBG("check_self - checking if host==us: %d==%d && "
+				" [%.*s] == [%.*s]\n", 
+					host->len,
+					sock_info[r].name.len,
+					host->len, host->s,
+					sock_info[r].name.len, sock_info[r].name.s
+			);
+		if ( (host->len==sock_info[r].name.len) && 
+	#ifdef USE_IPV6
+			(strncasecmp(host->s, sock_info[r].name.s,
+								 sock_info[r].name.len)==0) /*slower*/
+	#else
+			(memcmp(host->s, sock_info[r].name.s, 
+								sock_info[r].name.len)==0)
+	#endif
+			)
+			break;
+	/* check if host == ip address */
+		if ( 	(!sock_info[r].is_ip) &&
+				(host->len==sock_info[r].address_str.len) && 
+	#ifdef USE_IPV6
+			(strncasecmp(host->s, sock_info[r].address_str.s,
+								 sock_info[r].address_str.len)==0) /*slower*/
+	#else
+			(memcmp(host->s, sock_info[r].address_str.s, 
+								sock_info[r].address_str.len)==0)
+	#endif
+			)
+			break;
+	}
+	if (r==sock_no){
+		DBG("check_self: host != me\n");
+		return 0;
+	}
+	return 1;
+}
+
+
 int forward_request( struct sip_msg* msg, struct proxy_l * p)
 {
 	unsigned int len;
@@ -247,7 +293,6 @@ int update_sock_struct_from_via( union sockaddr_union* to,
 /* removes first via & sends msg to the second */
 int forward_reply(struct sip_msg* msg)
 {
-	int  r;
 	char* new_buf;
 	union sockaddr_union* to;
 	struct socket_info* send_sock;
@@ -258,27 +303,7 @@ int forward_reply(struct sip_msg* msg)
 	new_buf=0;
 	/*check if first via host = us */
 	if (check_via){
-		for (r=0; r<sock_no; r++)
-		{
-			DBG("forward_reply - checking if via==us: %d==%d && "
-					" [%.*s] == [%.*s]\n", 
-					msg->via1->host.len,
-					sock_info[r].name.len,
-					msg->via1->host.len, msg->via1->host.s,
-					sock_info[r].name.len, sock_info[r].name.s
-				);
-			if ( (msg->via1->host.len==sock_info[r].name.len) && 
-	#ifdef USE_IPV6
-					(strncasecmp(msg->via1->host.s, sock_info[r].name.s,
-								 sock_info[r].name.len)==0) /*slower*/
-	#else
-					(memcmp(msg->via1->host.s, sock_info[r].name.s, 
-										sock_info[r].name.len)==0)
-	#endif
-					)
-				break;
-		}
-		if (r==sock_no){
+		if (check_self(&(msg->via1->host))!=1){
 			LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
 					" %.*s\n", msg->via1->host.len, msg->via1->host.s);
 			/* send error msg back? */

+ 1 - 0
forward.h

@@ -13,6 +13,7 @@
 
 
 struct socket_info* get_send_socket(union sockaddr_union* su);
+int check_self(str* host);
 int forward_request( struct sip_msg* msg,  struct proxy_l* p);
 int update_sock_struct_from_via( union sockaddr_union* to,
 								struct via_body* via );

+ 1 - 0
ip_addr.h

@@ -53,6 +53,7 @@ struct socket_info{
 	str address_str;        /* ip address converted to string -- optimization*/
 	unsigned short port_no;  /* port number */
 	str port_no_str; /* port number converted to string -- optimization*/
+	int is_ip; /* 1 if name is an ip address, 0 if not  -- optimization*/
 };
 
 

+ 8 - 2
main.c

@@ -197,7 +197,7 @@ int log_stderr = 0;
 /* check if reply first via host==us */
 int check_via =  0;        
 /* shall use stateful synonym branches? faster but not reboot-safe */
-int syn_branch = 0;
+int syn_branch = 1;
 /* should replies include extensive warnings? by default yes,
    good for trouble-shooting
 */
@@ -956,8 +956,14 @@ int main(int argc, char** argv)
 			goto error;
 		}
 		strncpy(sock_info[r].address_str.s, tmp, strlen(tmp)+1);
+		/* set is_ip (1 if name is an ip address, 0 otherwise) */
 		sock_info[r].address_str.len=strlen(tmp);
-		
+		if 	(	(sock_info[r].address_str.len==sock_info[r].name.len)&&
+				(strncasecmp(sock_info[r].address_str.s, sock_info[r].name.s,
+						 sock_info[r].address_str.len)==0)
+			)	sock_info[r].is_ip=1;
+		else sock_info[r].is_ip=0;
+			
 		if (sock_info[r].port_no==0) sock_info[r].port_no=port_no;
 		port_no_str_len=snprintf(port_no_str, MAX_PORT_LEN, ":%d", 
 									(unsigned short) sock_info[r].port_no);

+ 2 - 0
parser/msg_parser.c

@@ -18,6 +18,7 @@
 #include "../error.h"
 #include "../globals.h"
 #include "parse_hname2.h"
+#include "parse_uri.h"
 
 #ifdef DEBUG_DMALLOC
 #include <mem/dmalloc.h>
@@ -463,6 +464,7 @@ void free_sip_msg(struct sip_msg* msg)
 	if (msg->add_rm)      free_lump_list(msg->add_rm);
 	if (msg->repl_add_rm) free_lump_list(msg->repl_add_rm);
 	if (msg->reply_lump)   free_reply_lump(msg->reply_lump);
+	if (msg->parsed_uri_ok) free_uri(&msg->parsed_uri);
 	pkg_free(msg->orig);
 	/* don't free anymore -- now a pointer to a static buffer */
 #	ifdef DYN_BUF

+ 14 - 1
parser/msg_parser.h

@@ -14,7 +14,6 @@
 #include "parse_cseq.h"
 #include "parse_to.h"
 #include "parse_via.h"
-#include "parse_uri.h"
 #include "parse_fline.h"
 #include "hf.h"
 
@@ -46,6 +45,18 @@ if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
 }
 
 
+
+struct sip_uri {
+	str user;     /* Username */
+	str passwd;   /* Password */
+	str host;     /* Host name */
+	str port;     /* Port number */
+	str params;   /* Parameters */
+	str headers;  
+};
+
+
+
 struct sip_msg {
 	unsigned int id;               /* message id, unique/process*/
 	struct msg_start first_line;   /* Message first line */
@@ -96,6 +107,8 @@ struct sip_msg {
 	     /* modifications */
 	
 	str new_uri; /* changed first line uri*/
+	int parsed_uri_ok; /* 1 if parsed_uri is valid, 0 if not */
+	struct sip_uri parsed_uri; /* speed-up > keep here the parsed uri*/
 	
 	struct lump* add_rm;         /* used for all the forwarded requests */
 	struct lump* repl_add_rm;    /* used for all the forwarded replies */

+ 27 - 0
parser/parse_uri.c

@@ -192,6 +192,33 @@ error:
 }
 
 
+
+int parse_sip_msg_uri(struct sip_msg* msg)
+{
+	char* tmp;
+	int tmp_len;
+	if (msg->parsed_uri_ok) return 1;
+	else{
+		if (msg->new_uri.s){
+			tmp=msg->new_uri.s;
+			tmp_len=msg->new_uri.len;
+		}else{
+			tmp=msg->first_line.u.request.uri.s;
+			tmp_len=msg->first_line.u.request.uri.len;
+		}
+		if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
+			LOG(L_ERR, "ERROR: parse_sip_msg_uri: bad uri <%*s>\n",
+						tmp_len, tmp);
+			msg->parsed_uri_ok=0;
+			return -1;
+		}
+		msg->parsed_uri_ok=1;
+		return 1;
+	}
+}
+
+
+
 void free_uri(struct sip_uri* u)
 {
 	if (u) {

+ 2 - 8
parser/parse_uri.h

@@ -11,15 +11,8 @@
 
 
 #include "../str.h"
+#include "../parser/msg_parser.h"
 
-struct sip_uri {
-	str user;     /* Username */
-	str passwd;   /* Password */
-	str host;     /* Host name */
-	str port;     /* Port number */
-	str params;   /* Parameters */
-	str headers;  
-};
 
 
 /* buf= pointer to begining of uri (sip:[email protected]:5060;a=b?h=i)
@@ -27,6 +20,7 @@ struct sip_uri {
  * returns: fills uri & returns <0 on error or 0 if ok 
  */
 int parse_uri(char *buf, int len, struct sip_uri* uri);
+int parse_sip_msg_uri(struct sip_msg* msg);
 
 void free_uri(struct sip_uri* u);
 

+ 22 - 4
route.c

@@ -16,12 +16,14 @@
 #include <netdb.h>
 
 #include "route.h"
+#include "forward.h"
 #include "dprint.h"
 #include "proxy.h"
 #include "action.h"
 #include "sr_module.h"
 #include "ip_addr.h"
 #include "resolve.h"
+#include "parser/parse_uri.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -242,6 +244,7 @@ static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
 	struct hostent* he;
 	char ** h;
 	int ret;
+	str tmp;
 
 	ret=-1;
 	switch(subtype){
@@ -275,6 +278,11 @@ static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
 				}
 			}
 			break;
+		case MYSELF_ST: /* check if it's one of our addresses*/
+			tmp.s=ip_addr2a(ip);
+			tmp.len=strlen(tmp.s);
+			ret=check_self(&tmp);
+			break;
 		default:
 			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
 						" src_ip or dst_ip (%d)\n", subtype);
@@ -304,11 +312,21 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
 				break;
 		case URI_O:
 				if(msg->new_uri.s){
-					ret=comp_str(msg->new_uri.s, e->r.param,
-									e->op, e->subtype);
+					if (e->subtype==MYSELF_ST){
+						if (parse_sip_msg_uri(msg)<0) ret=-1;
+						else	ret=check_self(&msg->parsed_uri.host);
+					}else{
+						ret=comp_str(msg->new_uri.s, e->r.param,
+										e->op, e->subtype);
+					}
 				}else{
-					ret=comp_str(msg->first_line.u.request.uri.s, e->r.param,
-									e->op, e->subtype);
+					if (e->subtype==MYSELF_ST){
+						if (parse_sip_msg_uri(msg)<0) ret=-1;
+						else	ret=check_self(&msg->parsed_uri.host);
+					}else{
+						ret=comp_str(msg->first_line.u.request.uri.s,
+										 e->r.param, e->op, e->subtype);
+					}
 				}
 				break;
 		case SRCIP_O:

+ 3 - 0
route_struct.c

@@ -160,6 +160,9 @@ void print_expr(struct expr* exp)
 			case NUMBER_ST:
 					DBG("%d",exp->r.intval);
 					break;
+			case MYSELF_ST:
+					DBG("_myself_");
+					break;
 			default:
 					DBG("type<%d>", exp->subtype);
 		}

+ 2 - 1
route_struct.h

@@ -32,7 +32,8 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		APPEND_BRANCH_T,
 		REVERT_URI_T };
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
-		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST };
+		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
+		MYSELF_ST };
 
 	
 struct expr{

+ 5 - 1
test/stateless.cfg

@@ -22,12 +22,16 @@ rev_dns=off      # (cmd. line: -R)
 #listen=127.0.0.1
 #listen=192.168.57.33
 #listen=192.168.57.72
-loop_checks=0
+#loop_checks=0
 # for more info: sip_router -h
 
 #modules
 
 
 route{
+	if (myself==uri){
+		log("\n\nfrom myself\n\n"); drop;
+	};
+	log("\n\n continue \n\n");
 	forward(uri:host, uri:port);
 }