Browse Source

- added the missing force_send_socket script command

Andrei Pelinescu-Onciul 21 years ago
parent
commit
6cd4883577
12 changed files with 114 additions and 19 deletions
  1. 1 1
      Makefile.defs
  2. 5 0
      NEWS
  3. 11 0
      action.c
  4. 4 0
      cfg.lex
  5. 17 14
      cfg.y
  6. 6 0
      etc/ser.cfg
  7. 8 0
      ip_addr.h
  8. 1 1
      main.c
  9. 27 1
      route.c
  10. 24 0
      route_struct.c
  11. 3 2
      route_struct.h
  12. 7 0
      socket_info.c

+ 1 - 1
Makefile.defs

@@ -50,7 +50,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 8
 SUBLEVEL =   99
-EXTRAVERSION = -dev19
+EXTRAVERSION = -dev20
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

+ 5 - 0
NEWS

@@ -107,6 +107,11 @@ core:
    unix_tx_timeout = 2000
        Timeout (in ms) used when sending replies through unix sockets.
  - new script commands:
+   force_send_socket([proto:]address[:port])
+       sends the message from the specified socket (it _must_ be one of the
+       sockets ser listens on). If the protocol doesn't match (e.g. udp
+       message "forced" to a tcp socket) the closest socket of the same
+       protocol is used.
    force_tcp_alias()
    force_tcp_alias(port)
        adds a tcp port alias for the current connection (if tcp).

+ 11 - 0
action.c

@@ -36,6 +36,7 @@
  *  2003-04-22  strip_tail added (jiri)
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
  *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
+ *  2004-11-30  added FORCE_SEND_SOCKET_T (andrei)
  */
 
 
@@ -663,6 +664,16 @@ int do_action(struct action* a, struct sip_msg* msg)
 #endif
 			ret=1; /* continue processing */
 			break;
+		case FORCE_SEND_SOCKET_T:
+			if (a->p1_type!=SOCKETINFO_ST){
+				LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
+						" type: %d\n", a->p1_type);
+				ret=E_BUG;
+				break;
+			}
+			msg->force_send_socket=(struct socket_info*)a->p1.data;
+			ret=1; /* continue processing */
+			break;
 		default:
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
 	}

+ 4 - 0
cfg.lex

@@ -51,6 +51,7 @@
  *              added MCAST_TTL (andrei)
  *  2004-10-08  more escapes: \", \xHH, \nnn and minor optimizations (andrei)
  *  2004-10-19  added FROM_URI and TO_URI (andrei)
+ *  2004-11-30  added force_send_socket
  */
 
 
@@ -129,6 +130,7 @@ IF				"if"
 ELSE			"else"
 SET_ADV_ADDRESS	"set_advertised_address"
 SET_ADV_PORT	"set_advertised_port"
+FORCE_SEND_SOCKET	"force_send_socket"
 
 /*ACTION LVALUES*/
 URIHOST			"uri:host"
@@ -321,6 +323,8 @@ EAT_ABLE	[\ \t\b\r]
 										return SET_ADV_ADDRESS; }
 <INITIAL>{SET_ADV_PORT}	{ count(); yylval.strval=yytext;
 										return SET_ADV_PORT; }
+<INITIAL>{FORCE_SEND_SOCKET}	{	count(); yylval.strval=yytext;
+									return FORCE_SEND_SOCKET; }
 
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }

+ 17 - 14
cfg.y

@@ -57,6 +57,7 @@
  * 2004-07-05  src_ip & dst_ip will detect ip addresses between quotes
  *              (andrei)
  * 2004-10-19  added FROM_URI, TO_URI (andrei)
+ * 2004-11-30  added force_send_socket (andrei)
  */
 
 
@@ -97,26 +98,20 @@
  with no built in alloca, like icc*/
 #undef _ALLOCA_H
 
-struct id_list{
-	char* name;
-	int proto;
-	int port;
-	struct id_list* next;
-};
 
 extern int yylex();
 static void yyerror(char* s);
 static char* tmp;
 static int i_tmp;
 static void* f_tmp;
-static struct id_list* lst_tmp;
+static struct socket_id* lst_tmp;
 static int rt;  /* Type of route block for find_export */
 static str* str_tmp;
 static str s_tmp;
 static struct ip_addr* ip_tmp;
 
 static void warn(char* s);
-static struct id_list* mk_listen_id(char*, int, int);
+static struct socket_id* mk_listen_id(char*, int, int);
  
 
 %}
@@ -129,7 +124,7 @@ static struct id_list* mk_listen_id(char*, int, int);
 	struct action* action;
 	struct net* ipnet;
 	struct ip_addr* ipaddr;
-	struct id_list* idlst;
+	struct socket_id* sockid;
 }
 
 /* terminals */
@@ -166,6 +161,7 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token ELSE
 %token SET_ADV_ADDRESS
 %token SET_ADV_PORT
+%token FORCE_SEND_SOCKET
 %token URIHOST
 %token URIPORT
 %token MAX_LEN
@@ -297,8 +293,8 @@ static struct id_list* mk_listen_id(char*, int, int);
 %type <ipnet> ipnet
 %type <strval> host
 %type <strval> listen_id
-%type <idlst>  id_lst
-%type <idlst>  phostport
+%type <sockid>  id_lst
+%type <sockid>  phostport
 %type <intval> proto port
 %type <intval> equalop strop intop
 %type <strval> host_sep
@@ -1609,6 +1605,13 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
 		| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, "
 														"string expected"); }
 		| SET_ADV_PORT  error {$$=0; yyerror("missing '(' or ')' ?"); }
+		| FORCE_SEND_SOCKET LPAREN phostport RPAREN {
+										$$=mk_action(FORCE_SEND_SOCKET_T,
+														SOCKID_ST, 0, $3, 0);
+													}
+		| FORCE_SEND_SOCKET LPAREN error RPAREN { $$=0; yyerror("bad argument,"
+											" [proto:]host[:port] expected"); }
+		| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
 		| ID LPAREN RPAREN			{ f_tmp=(void*)find_export($1, 0, rt);
 									   if (f_tmp==0){
 										   if (find_export($1, 0, 0)) {
@@ -1690,10 +1693,10 @@ static void yyerror(char* s)
 }
 
 
-static struct id_list* mk_listen_id(char* host, int proto, int port)
+static struct socket_id* mk_listen_id(char* host, int proto, int port)
 {
-	struct id_list* l;
-	l=pkg_malloc(sizeof(struct id_list));
+	struct socket_id* l;
+	l=pkg_malloc(sizeof(struct socket_id));
 	if (l==0){
 		LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
 	}else{

+ 6 - 0
etc/ser.cfg

@@ -80,6 +80,12 @@ route{
 		sl_send_reply("513", "Message too big");
 		break;
 	};
+	
+	if (src_ip==193.175.135.0/24){
+		force_send_socket(smaug:5080);
+		forward(193.175.135.179);
+		break;
+	}
 
 	# we record-route all messages -- to make sure that
 	# subsequent messages will go through our proxy; that's

+ 8 - 0
ip_addr.h

@@ -118,6 +118,14 @@ struct dest_info{
 };
 
 
+struct socket_id{
+	char* name;
+	int proto;
+	int port;
+	struct socket_id* next;
+};
+
+
 
 /* len of the sockaddr */
 #ifdef HAVE_SOCKADDR_SA_LEN

+ 1 - 1
main.c

@@ -1431,7 +1431,7 @@ try_again:
 	}
 	/* fix routing lists */
 	if ( (r=fix_rls())!=0){
-		fprintf(stderr, "ERROR: error %x while trying to fix configuration\n",
+		fprintf(stderr, "ERROR: error %d while trying to fix configuration\n",
 						r);
 		goto error;
 	};

+ 27 - 1
route.c

@@ -61,6 +61,7 @@
 #include "sr_module.h"
 #include "ip_addr.h"
 #include "resolve.h"
+#include "socket_info.h"
 #include "parser/parse_uri.h"
 #include "parser/parse_from.h"
 #include "parser/parse_to.h"
@@ -154,6 +155,9 @@ static int fix_actions(struct action* a)
 	cmd_export_t* cmd;
 	struct sr_module* mod;
 	str s;
+	struct hostent* he;
+	struct ip_addr ip;
+	struct socket_info* si;
 	
 	if (a==0){
 		LOG(L_CRIT,"BUG: fix_actions: null pointer\n");
@@ -242,7 +246,29 @@ static int fix_actions(struct action* a)
 						}
 					}
 				}
-			
+				break;
+			case FORCE_SEND_SOCKET_T:
+				if (t->p1_type!=SOCKID_ST){
+					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
+								"%d for force_send_socket\n",
+								t->p1_type);
+					return E_BUG;
+				}
+				he=resolvehost(((struct socket_id*)t->p1.data)->name);
+				if (he==0) return E_BAD_ADDRESS;
+				hostent2ip_addr(&ip, he, 0);
+				si=find_si(&ip, ((struct socket_id*)t->p1.data)->port,
+								((struct socket_id*)t->p1.data)->proto);
+				if (si==0){
+					LOG(L_ERR, "ERROR: fix_actions: bad force_send_socket"
+							" argument: %s:%d (ser doesn't listen on it)\n",
+							((struct socket_id*)t->p1.data)->name,
+							((struct socket_id*)t->p1.data)->port);
+					return E_BAD_ADDRESS;
+				}
+				t->p1.data=si;
+				t->p1_type=SOCKETINFO_ST;
+				break;
 		}
 	}
 	return 0;

+ 24 - 0
route_struct.c

@@ -340,6 +340,9 @@ void print_action(struct action* a)
 			case AVP_TO_URI_T:
 					DBG("avp_to_attr");
 					break;
+			case FORCE_SEND_SOCKET_T:
+					DBG("force_send_socket");
+					break;
 			default:
 					DBG("UNKNOWN(");
 		}
@@ -362,6 +365,13 @@ void print_action(struct action* a)
 			case CMDF_ST:
 					DBG("f_ptr<%p>",t->p1.data);
 					break;
+			case SOCKID_ST:
+					DBG("%d:%s:%d",
+							((struct socket_id*)t->p1.data)->proto,
+							((struct socket_id*)t->p1.data)->name,
+							((struct socket_id*)t->p1.data)->port
+							);
+					break;
 			default:
 					DBG("type<%d>", t->p1_type);
 		}
@@ -381,6 +391,13 @@ void print_action(struct action* a)
 			case ACTIONS_ST:
 					print_action((struct action*)t->p2.data);
 					break;
+			case SOCKID_ST:
+					DBG("%d:%s:%d",
+							((struct socket_id*)t->p1.data)->proto,
+							((struct socket_id*)t->p1.data)->name,
+							((struct socket_id*)t->p1.data)->port
+							);
+					break;
 			default:
 					DBG(", type<%d>", t->p2_type);
 		}
@@ -400,6 +417,13 @@ void print_action(struct action* a)
 			case ACTIONS_ST:
 					print_action((struct action*)t->p3.data);
 					break;
+			case SOCKID_ST:
+					DBG("%d:%s:%d",
+							((struct socket_id*)t->p1.data)->proto,
+							((struct socket_id*)t->p1.data)->name,
+							((struct socket_id*)t->p1.data)->port
+							);
+					break;
 			default:
 					DBG(", type<%d>", t->p3_type);
 		}

+ 3 - 2
route_struct.h

@@ -75,11 +75,12 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		SET_ADV_PORT_T,
 		FORCE_TCP_ALIAS_T,
 		LOAD_AVP_T,
-		AVP_TO_URI_T
+		AVP_TO_URI_T,
+		FORCE_SEND_SOCKET_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,
-		MYSELF_ST, STR_ST };
+		MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST };
 
 	
 struct expr{

+ 7 - 0
socket_info.c

@@ -361,6 +361,13 @@ int add_listen_iface(char* name, unsigned short port, unsigned short proto,
 			LOG(L_ERR, "ERROR: add_listen_iface: get_sock_info_list failed\n");
 			goto error;
 		}
+		if (port==0){ /* use default port */
+			port=
+#ifdef USE_TLS
+				((c_proto)==PROTO_TLS)?tls_port_no:
+#endif
+				port_no;
+		}
 		if (new_sock2list(name, port, c_proto, flags, list)<0){
 			LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
 			goto error;