... | ... |
@@ -107,6 +107,11 @@ core: |
107 | 107 |
unix_tx_timeout = 2000 |
108 | 108 |
Timeout (in ms) used when sending replies through unix sockets. |
109 | 109 |
- new script commands: |
110 |
+ force_send_socket([proto:]address[:port]) |
|
111 |
+ sends the message from the specified socket (it _must_ be one of the |
|
112 |
+ sockets ser listens on). If the protocol doesn't match (e.g. udp |
|
113 |
+ message "forced" to a tcp socket) the closest socket of the same |
|
114 |
+ protocol is used. |
|
110 | 115 |
force_tcp_alias() |
111 | 116 |
force_tcp_alias(port) |
112 | 117 |
adds a tcp port alias for the current connection (if tcp). |
... | ... |
@@ -36,6 +36,7 @@ |
36 | 36 |
* 2003-04-22 strip_tail added (jiri) |
37 | 37 |
* 2003-10-02 added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei) |
38 | 38 |
* 2003-10-29 added FORCE_TCP_ALIAS_T (andrei) |
39 |
+ * 2004-11-30 added FORCE_SEND_SOCKET_T (andrei) |
|
39 | 40 |
*/ |
40 | 41 |
|
41 | 42 |
|
... | ... |
@@ -663,6 +664,16 @@ int do_action(struct action* a, struct sip_msg* msg) |
663 | 664 |
#endif |
664 | 665 |
ret=1; /* continue processing */ |
665 | 666 |
break; |
667 |
+ case FORCE_SEND_SOCKET_T: |
|
668 |
+ if (a->p1_type!=SOCKETINFO_ST){ |
|
669 |
+ LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument" |
|
670 |
+ " type: %d\n", a->p1_type); |
|
671 |
+ ret=E_BUG; |
|
672 |
+ break; |
|
673 |
+ } |
|
674 |
+ msg->force_send_socket=(struct socket_info*)a->p1.data; |
|
675 |
+ ret=1; /* continue processing */ |
|
676 |
+ break; |
|
666 | 677 |
default: |
667 | 678 |
LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type); |
668 | 679 |
} |
... | ... |
@@ -51,6 +51,7 @@ |
51 | 51 |
* added MCAST_TTL (andrei) |
52 | 52 |
* 2004-10-08 more escapes: \", \xHH, \nnn and minor optimizations (andrei) |
53 | 53 |
* 2004-10-19 added FROM_URI and TO_URI (andrei) |
54 |
+ * 2004-11-30 added force_send_socket |
|
54 | 55 |
*/ |
55 | 56 |
|
56 | 57 |
|
... | ... |
@@ -129,6 +130,7 @@ IF "if" |
129 | 130 |
ELSE "else" |
130 | 131 |
SET_ADV_ADDRESS "set_advertised_address" |
131 | 132 |
SET_ADV_PORT "set_advertised_port" |
133 |
+FORCE_SEND_SOCKET "force_send_socket" |
|
132 | 134 |
|
133 | 135 |
/*ACTION LVALUES*/ |
134 | 136 |
URIHOST "uri:host" |
... | ... |
@@ -321,6 +323,8 @@ EAT_ABLE [\ \t\b\r] |
321 | 323 |
return SET_ADV_ADDRESS; } |
322 | 324 |
<INITIAL>{SET_ADV_PORT} { count(); yylval.strval=yytext; |
323 | 325 |
return SET_ADV_PORT; } |
326 |
+<INITIAL>{FORCE_SEND_SOCKET} { count(); yylval.strval=yytext; |
|
327 |
+ return FORCE_SEND_SOCKET; } |
|
324 | 328 |
|
325 | 329 |
<INITIAL>{URIHOST} { count(); yylval.strval=yytext; return URIHOST; } |
326 | 330 |
<INITIAL>{URIPORT} { count(); yylval.strval=yytext; return URIPORT; } |
... | ... |
@@ -57,6 +57,7 @@ |
57 | 57 |
* 2004-07-05 src_ip & dst_ip will detect ip addresses between quotes |
58 | 58 |
* (andrei) |
59 | 59 |
* 2004-10-19 added FROM_URI, TO_URI (andrei) |
60 |
+ * 2004-11-30 added force_send_socket (andrei) |
|
60 | 61 |
*/ |
61 | 62 |
|
62 | 63 |
|
... | ... |
@@ -97,26 +98,20 @@ |
97 | 98 |
with no built in alloca, like icc*/ |
98 | 99 |
#undef _ALLOCA_H |
99 | 100 |
|
100 |
-struct id_list{ |
|
101 |
- char* name; |
|
102 |
- int proto; |
|
103 |
- int port; |
|
104 |
- struct id_list* next; |
|
105 |
-}; |
|
106 | 101 |
|
107 | 102 |
extern int yylex(); |
108 | 103 |
static void yyerror(char* s); |
109 | 104 |
static char* tmp; |
110 | 105 |
static int i_tmp; |
111 | 106 |
static void* f_tmp; |
112 |
-static struct id_list* lst_tmp; |
|
107 |
+static struct socket_id* lst_tmp; |
|
113 | 108 |
static int rt; /* Type of route block for find_export */ |
114 | 109 |
static str* str_tmp; |
115 | 110 |
static str s_tmp; |
116 | 111 |
static struct ip_addr* ip_tmp; |
117 | 112 |
|
118 | 113 |
static void warn(char* s); |
119 |
-static struct id_list* mk_listen_id(char*, int, int); |
|
114 |
+static struct socket_id* mk_listen_id(char*, int, int); |
|
120 | 115 |
|
121 | 116 |
|
122 | 117 |
%} |
... | ... |
@@ -129,7 +124,7 @@ static struct id_list* mk_listen_id(char*, int, int); |
129 | 124 |
struct action* action; |
130 | 125 |
struct net* ipnet; |
131 | 126 |
struct ip_addr* ipaddr; |
132 |
- struct id_list* idlst; |
|
127 |
+ struct socket_id* sockid; |
|
133 | 128 |
} |
134 | 129 |
|
135 | 130 |
/* terminals */ |
... | ... |
@@ -166,6 +161,7 @@ static struct id_list* mk_listen_id(char*, int, int); |
166 | 161 |
%token ELSE |
167 | 162 |
%token SET_ADV_ADDRESS |
168 | 163 |
%token SET_ADV_PORT |
164 |
+%token FORCE_SEND_SOCKET |
|
169 | 165 |
%token URIHOST |
170 | 166 |
%token URIPORT |
171 | 167 |
%token MAX_LEN |
... | ... |
@@ -297,8 +293,8 @@ static struct id_list* mk_listen_id(char*, int, int); |
297 | 293 |
%type <ipnet> ipnet |
298 | 294 |
%type <strval> host |
299 | 295 |
%type <strval> listen_id |
300 |
-%type <idlst> id_lst |
|
301 |
-%type <idlst> phostport |
|
296 |
+%type <sockid> id_lst |
|
297 |
+%type <sockid> phostport |
|
302 | 298 |
%type <intval> proto port |
303 | 299 |
%type <intval> equalop strop intop |
304 | 300 |
%type <strval> host_sep |
... | ... |
@@ -1609,6 +1605,13 @@ cmd: FORWARD LPAREN host RPAREN { $$=mk_action( FORWARD_T, |
1609 | 1605 |
| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
1610 | 1606 |
"string expected"); } |
1611 | 1607 |
| SET_ADV_PORT error {$$=0; yyerror("missing '(' or ')' ?"); } |
1608 |
+ | FORCE_SEND_SOCKET LPAREN phostport RPAREN { |
|
1609 |
+ $$=mk_action(FORCE_SEND_SOCKET_T, |
|
1610 |
+ SOCKID_ST, 0, $3, 0); |
|
1611 |
+ } |
|
1612 |
+ | FORCE_SEND_SOCKET LPAREN error RPAREN { $$=0; yyerror("bad argument," |
|
1613 |
+ " [proto:]host[:port] expected"); } |
|
1614 |
+ | FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); } |
|
1612 | 1615 |
| ID LPAREN RPAREN { f_tmp=(void*)find_export($1, 0, rt); |
1613 | 1616 |
if (f_tmp==0){ |
1614 | 1617 |
if (find_export($1, 0, 0)) { |
... | ... |
@@ -1690,10 +1693,10 @@ static void yyerror(char* s) |
1690 | 1693 |
} |
1691 | 1694 |
|
1692 | 1695 |
|
1693 |
-static struct id_list* mk_listen_id(char* host, int proto, int port) |
|
1696 |
+static struct socket_id* mk_listen_id(char* host, int proto, int port) |
|
1694 | 1697 |
{ |
1695 |
- struct id_list* l; |
|
1696 |
- l=pkg_malloc(sizeof(struct id_list)); |
|
1698 |
+ struct socket_id* l; |
|
1699 |
+ l=pkg_malloc(sizeof(struct socket_id)); |
|
1697 | 1700 |
if (l==0){ |
1698 | 1701 |
LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n"); |
1699 | 1702 |
}else{ |
... | ... |
@@ -80,6 +80,12 @@ route{ |
80 | 80 |
sl_send_reply("513", "Message too big"); |
81 | 81 |
break; |
82 | 82 |
}; |
83 |
+ |
|
84 |
+ if (src_ip==193.175.135.0/24){ |
|
85 |
+ force_send_socket(smaug:5080); |
|
86 |
+ forward(193.175.135.179); |
|
87 |
+ break; |
|
88 |
+ } |
|
83 | 89 |
|
84 | 90 |
# we record-route all messages -- to make sure that |
85 | 91 |
# subsequent messages will go through our proxy; that's |
... | ... |
@@ -1431,7 +1431,7 @@ try_again: |
1431 | 1431 |
} |
1432 | 1432 |
/* fix routing lists */ |
1433 | 1433 |
if ( (r=fix_rls())!=0){ |
1434 |
- fprintf(stderr, "ERROR: error %x while trying to fix configuration\n", |
|
1434 |
+ fprintf(stderr, "ERROR: error %d while trying to fix configuration\n", |
|
1435 | 1435 |
r); |
1436 | 1436 |
goto error; |
1437 | 1437 |
}; |
... | ... |
@@ -61,6 +61,7 @@ |
61 | 61 |
#include "sr_module.h" |
62 | 62 |
#include "ip_addr.h" |
63 | 63 |
#include "resolve.h" |
64 |
+#include "socket_info.h" |
|
64 | 65 |
#include "parser/parse_uri.h" |
65 | 66 |
#include "parser/parse_from.h" |
66 | 67 |
#include "parser/parse_to.h" |
... | ... |
@@ -154,6 +155,9 @@ static int fix_actions(struct action* a) |
154 | 155 |
cmd_export_t* cmd; |
155 | 156 |
struct sr_module* mod; |
156 | 157 |
str s; |
158 |
+ struct hostent* he; |
|
159 |
+ struct ip_addr ip; |
|
160 |
+ struct socket_info* si; |
|
157 | 161 |
|
158 | 162 |
if (a==0){ |
159 | 163 |
LOG(L_CRIT,"BUG: fix_actions: null pointer\n"); |
... | ... |
@@ -242,7 +246,29 @@ static int fix_actions(struct action* a) |
242 | 246 |
} |
243 | 247 |
} |
244 | 248 |
} |
245 |
- |
|
249 |
+ break; |
|
250 |
+ case FORCE_SEND_SOCKET_T: |
|
251 |
+ if (t->p1_type!=SOCKID_ST){ |
|
252 |
+ LOG(L_CRIT, "BUG: fix_actions: invalid subtype" |
|
253 |
+ "%d for force_send_socket\n", |
|
254 |
+ t->p1_type); |
|
255 |
+ return E_BUG; |
|
256 |
+ } |
|
257 |
+ he=resolvehost(((struct socket_id*)t->p1.data)->name); |
|
258 |
+ if (he==0) return E_BAD_ADDRESS; |
|
259 |
+ hostent2ip_addr(&ip, he, 0); |
|
260 |
+ si=find_si(&ip, ((struct socket_id*)t->p1.data)->port, |
|
261 |
+ ((struct socket_id*)t->p1.data)->proto); |
|
262 |
+ if (si==0){ |
|
263 |
+ LOG(L_ERR, "ERROR: fix_actions: bad force_send_socket" |
|
264 |
+ " argument: %s:%d (ser doesn't listen on it)\n", |
|
265 |
+ ((struct socket_id*)t->p1.data)->name, |
|
266 |
+ ((struct socket_id*)t->p1.data)->port); |
|
267 |
+ return E_BAD_ADDRESS; |
|
268 |
+ } |
|
269 |
+ t->p1.data=si; |
|
270 |
+ t->p1_type=SOCKETINFO_ST; |
|
271 |
+ break; |
|
246 | 272 |
} |
247 | 273 |
} |
248 | 274 |
return 0; |
... | ... |
@@ -340,6 +340,9 @@ void print_action(struct action* a) |
340 | 340 |
case AVP_TO_URI_T: |
341 | 341 |
DBG("avp_to_attr"); |
342 | 342 |
break; |
343 |
+ case FORCE_SEND_SOCKET_T: |
|
344 |
+ DBG("force_send_socket"); |
|
345 |
+ break; |
|
343 | 346 |
default: |
344 | 347 |
DBG("UNKNOWN("); |
345 | 348 |
} |
... | ... |
@@ -362,6 +365,13 @@ void print_action(struct action* a) |
362 | 365 |
case CMDF_ST: |
363 | 366 |
DBG("f_ptr<%p>",t->p1.data); |
364 | 367 |
break; |
368 |
+ case SOCKID_ST: |
|
369 |
+ DBG("%d:%s:%d", |
|
370 |
+ ((struct socket_id*)t->p1.data)->proto, |
|
371 |
+ ((struct socket_id*)t->p1.data)->name, |
|
372 |
+ ((struct socket_id*)t->p1.data)->port |
|
373 |
+ ); |
|
374 |
+ break; |
|
365 | 375 |
default: |
366 | 376 |
DBG("type<%d>", t->p1_type); |
367 | 377 |
} |
... | ... |
@@ -381,6 +391,13 @@ void print_action(struct action* a) |
381 | 391 |
case ACTIONS_ST: |
382 | 392 |
print_action((struct action*)t->p2.data); |
383 | 393 |
break; |
394 |
+ case SOCKID_ST: |
|
395 |
+ DBG("%d:%s:%d", |
|
396 |
+ ((struct socket_id*)t->p1.data)->proto, |
|
397 |
+ ((struct socket_id*)t->p1.data)->name, |
|
398 |
+ ((struct socket_id*)t->p1.data)->port |
|
399 |
+ ); |
|
400 |
+ break; |
|
384 | 401 |
default: |
385 | 402 |
DBG(", type<%d>", t->p2_type); |
386 | 403 |
} |
... | ... |
@@ -400,6 +417,13 @@ void print_action(struct action* a) |
400 | 417 |
case ACTIONS_ST: |
401 | 418 |
print_action((struct action*)t->p3.data); |
402 | 419 |
break; |
420 |
+ case SOCKID_ST: |
|
421 |
+ DBG("%d:%s:%d", |
|
422 |
+ ((struct socket_id*)t->p1.data)->proto, |
|
423 |
+ ((struct socket_id*)t->p1.data)->name, |
|
424 |
+ ((struct socket_id*)t->p1.data)->port |
|
425 |
+ ); |
|
426 |
+ break; |
|
403 | 427 |
default: |
404 | 428 |
DBG(", type<%d>", t->p3_type); |
405 | 429 |
} |
... | ... |
@@ -75,11 +75,12 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T, |
75 | 75 |
SET_ADV_PORT_T, |
76 | 76 |
FORCE_TCP_ALIAS_T, |
77 | 77 |
LOAD_AVP_T, |
78 |
- AVP_TO_URI_T |
|
78 |
+ AVP_TO_URI_T, |
|
79 |
+ FORCE_SEND_SOCKET_T |
|
79 | 80 |
}; |
80 | 81 |
enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST, |
81 | 82 |
EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST, |
82 |
- MYSELF_ST, STR_ST }; |
|
83 |
+ MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST }; |
|
83 | 84 |
|
84 | 85 |
|
85 | 86 |
struct expr{ |
... | ... |
@@ -361,6 +361,13 @@ int add_listen_iface(char* name, unsigned short port, unsigned short proto, |
361 | 361 |
LOG(L_ERR, "ERROR: add_listen_iface: get_sock_info_list failed\n"); |
362 | 362 |
goto error; |
363 | 363 |
} |
364 |
+ if (port==0){ /* use default port */ |
|
365 |
+ port= |
|
366 |
+#ifdef USE_TLS |
|
367 |
+ ((c_proto)==PROTO_TLS)?tls_port_no: |
|
368 |
+#endif |
|
369 |
+ port_no; |
|
370 |
+ } |
|
364 | 371 |
if (new_sock2list(name, port, c_proto, flags, list)<0){ |
365 | 372 |
LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n"); |
366 | 373 |
goto error; |