... | ... |
@@ -1,3 +1,29 @@ |
1 |
+------------------------------------------------------------------------- |
|
2 |
+IMPORTANT NOTES |
|
3 |
+ |
|
4 |
+1) The GPL applies to this copy of SIP Express Router software (ser). |
|
5 |
+ For a license to use the ser software under conditions |
|
6 |
+ other than those described here, or to purchase support for this |
|
7 |
+ software, please contact iptel.org by e-mail at the following addresses: |
|
8 |
+ |
|
9 |
+ info@iptel.org |
|
10 |
+ |
|
11 |
+ (see http://www.gnu.org/copyleft/gpl-faq.html#TOCHeardOtherLicense |
|
12 |
+ for an explanation how parallel licenses comply with GPL) |
|
13 |
+ |
|
14 |
+2) ser software allows programmers to plug-in external modules to the |
|
15 |
+ core part. Note that GPL mandates all plug-ins developed for the |
|
16 |
+ ser software released under GPL license to be GPL-ed as well. |
|
17 |
+ |
|
18 |
+ (see http://www.gnu.org/copyleft/gpl-faq.html#GPLAndPlugins |
|
19 |
+ for a detailed explanation) |
|
20 |
+ |
|
21 |
+3) Note that the GPL bellow is copyrighted by the Free Software Foundation, |
|
22 |
+ but the ser software is copyrighted by iptel.org. |
|
23 |
+ |
|
24 |
+ |
|
25 |
+------------------------------------------------------------------------- |
|
26 |
+ |
|
1 | 27 |
GNU GENERAL PUBLIC LICENSE |
2 | 28 |
Version 2, June 1991 |
3 | 29 |
|
... | ... |
@@ -10,7 +10,7 @@ auto_gen=lex.yy.c cfg.tab.c #lexx, yacc etc |
10 | 10 |
#include source related defs |
11 | 11 |
include Makefile.sources |
12 | 12 |
|
13 |
-exclude_modules=CVS mysql pike |
|
13 |
+exclude_modules=CVS mysql pike |
|
14 | 14 |
static_modules= |
15 | 15 |
static_modules_path=$(addprefix modules/, $(static_modules)) |
16 | 16 |
extra_sources=$(wildcard $(addsuffix /*.c, $(static_modules_path))) |
... | ... |
@@ -76,9 +76,6 @@ INSTALL-MAN = $(INSTALL) -m 644 |
76 | 76 |
# issues additional debugging information if lock/unlock is called |
77 | 77 |
# -DFAST_LOCK |
78 | 78 |
# uses fast arhitecture specific locking (see the arh. specific section) |
79 |
-# -DNOISY_REPLIES |
|
80 |
-# turns on appending User-agent and Content-length:0 to ser-generated |
|
81 |
-# replies; |
|
82 | 79 |
# -DBUSY_WAIT |
83 | 80 |
# uses busy waiting on the lock |
84 | 81 |
# -DADAPTIVE_WAIT |
... | ... |
@@ -90,37 +87,29 @@ INSTALL-MAN = $(INSTALL) -m 644 |
90 | 87 |
# -DNOSMP |
91 | 88 |
# don't use smp compliant locking (faster but won't work on SMP machines) |
92 | 89 |
# (not yet enabled) |
93 |
-# -DWAIT |
|
94 |
-# protection against race condiditions; turn off only for debugging; |
|
95 |
-# to become non-optional if stable |
|
96 |
-# |
|
97 |
-# -SILENT_FR |
|
98 |
-# if defined, when FR timer hits (in tm) cancel is sent only if forking |
|
99 |
-# if used; otherwise, just delete the transaction without doing anything |
|
90 |
+# -DNO_PINGTEL_TAG_HACK |
|
91 |
+# if enabled, To-header-field will be less liberal and will not accept |
|
92 |
+# 'tag=' (tag parameter with equal sign and without value); it is called |
|
93 |
+# this way because such message was sighted from a Pingtel phone |
|
100 | 94 |
|
101 | 95 |
DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \ |
102 | 96 |
-DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"'\ |
103 | 97 |
-DPKG_MALLOC \ |
104 | 98 |
-DSHM_MEM -DSHM_MMAP \ |
105 | 99 |
-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \ |
106 |
- -DWAIT \ |
|
107 |
- -DSILENT_FR \ |
|
108 |
- -DNOISY_REPLIES -DVERY_NOISY_REPLIES\ |
|
109 |
- -DPINGTEL_TAG_HACK\ |
|
110 |
- -DF_MALLOC \ |
|
111 |
- -DUSE_SYNONIM\ |
|
112 | 100 |
-DUSE_IPV6 \ |
101 |
+ -DEXTRA_DEBUG \ |
|
102 |
+ -DVQ_MALLOC -DDBG_QM_MALLOC \ |
|
103 |
+ #-DCONTACT_BUG |
|
104 |
+ #-DF_MALLOC \ |
|
105 |
+ #-DDBG_LOCK |
|
113 | 106 |
#-DNO_DEBUG \ |
114 | 107 |
#-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=0 \ |
115 | 108 |
#-DNOSMP \ |
116 | 109 |
#-DEXTRA_DEBUG |
117 |
- #-DVQ_MALLOC -DDBG_LOCK #-DSTATS |
|
118 |
- #-DDBG_QM_MALLOC |
|
119 |
-# -DUSE_SHM_MEM |
|
120 |
-#-DSTATS |
|
121 |
-#-DNO_LOG |
|
122 |
- |
|
123 |
- |
|
110 |
+ #-DUSE_SHM_MEM |
|
111 |
+ #-DSTATS |
|
112 |
+ #-DNO_LOG |
|
124 | 113 |
|
125 | 114 |
#PROFILE= -pg #set this if you want profiling |
126 | 115 |
#mode = debug |
... | ... |
@@ -3,33 +3,59 @@ |
3 | 3 |
List of currently available ser modules |
4 | 4 |
---------------------------------------------------------- |
5 | 5 |
Name Use Maturity Purpose/Depends on |
6 |
+(owner) |
|
6 | 7 |
---------------------------------------------------------- |
7 | 8 |
acc regular stable transaction accounting |
8 |
- /example (the module servers also |
|
9 |
+(jku) /example (the module servers also |
|
9 | 10 |
as example of how to bind |
10 | 11 |
to transaction management) |
11 | 12 |
-tm |
13 |
+ |
|
12 | 14 |
auth regular stable digest authentication |
13 |
- -sl |
|
15 |
+(jja) -sl |
|
14 | 16 |
-mysql |
17 |
+ |
|
15 | 18 |
cpl experimental alpha Call Processing Language |
19 |
+(bia) |
|
20 |
+ |
|
16 | 21 |
ext experimental alpha Execution of external URI |
17 |
- processing logic |
|
22 |
+(bia) processing logic |
|
23 |
+ |
|
18 | 24 |
im temporary alpha Stateless instant messaging |
19 |
- client |
|
25 |
+(bia) client |
|
26 |
+ |
|
20 | 27 |
jabber experimental beta SIP2Jabber gateway |
28 |
+(dcm) |
|
29 |
+ |
|
21 | 30 |
maxfwd regular stable Max-Forwards check |
31 |
+(bia) |
|
32 |
+ |
|
22 | 33 |
mysql regular stable supporting MySql interface |
34 |
+(jja) |
|
35 |
+ |
|
23 | 36 |
pike experimental alpha excessive load detection |
37 |
+(bia) |
|
38 |
+ |
|
24 | 39 |
print example stable Printing Message to stdout |
40 |
+(ape) |
|
41 |
+ |
|
25 | 42 |
rr regular stable Record-Routing |
43 |
+(jja) |
|
44 |
+ |
|
26 | 45 |
sl regular stable Stateless Replies |
46 |
+(bia) |
|
47 |
+ |
|
27 | 48 |
sms regular stable SMS gateway |
28 |
- -tm |
|
49 |
+(bia) -tm |
|
50 |
+ |
|
29 | 51 |
textops regular stable Message Textual Operations |
52 |
+(ape) |
|
53 |
+ |
|
30 | 54 |
tm regular beta Transaction Management |
55 |
+(ape) |
|
56 |
+ |
|
31 | 57 |
usrloc regular stable User Location |
32 |
- -sl |
|
58 |
+(jja) -sl |
|
33 | 59 |
-mysql (optionally) |
34 | 60 |
|
35 | 61 |
|
... | ... |
@@ -44,3 +70,8 @@ ser programmers. |
44 | 70 |
Maturity is label as stable if a module has been deployed |
45 | 71 |
for longer time, alpha if it is still being developed and |
46 | 72 |
beta if it is under test. |
73 |
+ |
|
74 |
+Modules underway include presence server functionality, |
|
75 |
+firewall control, message store and more. If you are |
|
76 |
+interested in any of these or other modules, write us |
|
77 |
+to info@iptel.org. |
... | ... |
@@ -16,16 +16,16 @@ x (different way) add request header bitmap field for the modules |
16 | 16 |
|
17 | 17 |
|
18 | 18 |
High priority: |
19 |
-- fix/replace T_REF/T_UNREF |
|
20 |
-- review all the tm locking |
|
19 |
+x fix/replace T_REF/T_UNREF |
|
20 |
+x review all the tm locking |
|
21 | 21 |
x if () {} else {} |
22 | 22 |
x plugin interface |
23 | 23 |
x ipv6 support |
24 |
-- reply ("response line") |
|
25 |
-- drop ACKs for our replies |
|
24 |
+x reply ("response line") |
|
25 |
+x drop ACKs for our replies |
|
26 | 26 |
- icmp error handling |
27 |
-- add To-tag (for the replies) |
|
28 |
-- add User-Agent (for the replies) |
|
27 |
+x add To-tag (for the replies) |
|
28 |
+x add User-Agent (for the replies) |
|
29 | 29 |
|
30 | 30 |
Low priority: |
31 | 31 |
x fix via address someday |
... | ... |
@@ -38,7 +38,7 @@ x forward to received= if present |
38 | 38 |
- exec improvments (add format strings to it) |
39 | 39 |
- command line switch for checking the config file syntax |
40 | 40 |
- config file version (a la sendmail) |
41 |
-- loop detection |
|
41 |
+0 loop detection |
|
42 | 42 |
- cfg. file reload |
43 | 43 |
- flags for using names or ip adresses in Via ? |
44 | 44 |
|
... | ... |
@@ -55,6 +55,6 @@ x the same for rpm |
55 | 55 |
- the same for FreeBSD and Slackware |
56 | 56 |
|
57 | 57 |
|
58 |
-- jku: branch hash computation over canonical values |
|
59 |
-- jku: loop checking |
|
58 |
+x jku: branch hash computation over canonical values |
|
59 |
+0 jku: loop checking |
|
60 | 60 |
- jku: try CRC as opposed to MD5 |
... | ... |
@@ -17,6 +17,7 @@ |
17 | 17 |
#include "sr_module.h" |
18 | 18 |
#include "mem/mem.h" |
19 | 19 |
#include "globals.h" |
20 |
+#include "dset.h" |
|
20 | 21 |
|
21 | 22 |
#include <sys/types.h> |
22 | 23 |
#include <sys/socket.h> |
... | ... |
@@ -179,6 +180,18 @@ int do_action(struct action* a, struct sip_msg* msg) |
179 | 180 |
ret=1; |
180 | 181 |
break; |
181 | 182 |
|
183 |
+ /* jku -- introduce a new branch */ |
|
184 |
+ case APPEND_BRANCH_T: |
|
185 |
+ if ((a->p1_type!=STRING_ST)) { |
|
186 |
+ LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n", |
|
187 |
+ a->p1_type ); |
|
188 |
+ ret=E_BUG; |
|
189 |
+ break; |
|
190 |
+ } |
|
191 |
+ ret=append_branch( msg, a->p1.string, |
|
192 |
+ a->p1.string ? strlen(a->p1.string):0 ); |
|
193 |
+ break; |
|
194 |
+ |
|
182 | 195 |
/* jku begin: is_length_greater_than */ |
183 | 196 |
case LEN_GT_T: |
184 | 197 |
if (a->p1_type!=NUMBER_ST) { |
... | ... |
@@ -281,6 +294,14 @@ int do_action(struct action* a, struct sip_msg* msg) |
281 | 294 |
} |
282 | 295 |
ret=1; |
283 | 296 |
break; |
297 |
+ case REVERT_URI_T: |
|
298 |
+ if (msg->new_uri.s) { |
|
299 |
+ pkg_free(msg->new_uri.s); |
|
300 |
+ msg->new_uri.len=0; |
|
301 |
+ msg->new_uri.s=0; |
|
302 |
+ }; |
|
303 |
+ ret=1; |
|
304 |
+ break; |
|
284 | 305 |
case SET_HOST_T: |
285 | 306 |
case SET_HOSTPORT_T: |
286 | 307 |
case SET_USER_T: |
... | ... |
@@ -46,6 +46,7 @@ SEND send |
46 | 46 |
LOG log |
47 | 47 |
ERROR error |
48 | 48 |
ROUTE route |
49 |
+REPLY_ROUTE reply_route |
|
49 | 50 |
EXEC exec |
50 | 51 |
SETFLAG setflag |
51 | 52 |
RESETFLAG resetflag |
... | ... |
@@ -57,8 +58,10 @@ SET_USER "rewriteuser"|"setuser"|"setu" |
57 | 58 |
SET_USERPASS "rewriteuserpass"|"setuserpass"|"setup" |
58 | 59 |
SET_PORT "rewriteport"|"setport"|"setp" |
59 | 60 |
SET_URI "rewriteuri"|"seturi" |
61 |
+REVERT_URI "revert_uri" |
|
60 | 62 |
PREFIX "prefix" |
61 | 63 |
STRIP "strip" |
64 |
+APPEND_BRANCH "append_branch" |
|
62 | 65 |
IF "if" |
63 | 66 |
ELSE "else" |
64 | 67 |
|
... | ... |
@@ -94,7 +97,12 @@ STAT statistics |
94 | 97 |
MAXBUFFER maxbuffer |
95 | 98 |
CHILDREN children |
96 | 99 |
CHECK_VIA check_via |
97 |
-LOOP_CHECKS loop_checks |
|
100 |
+SYN_BRANCH syn_branch |
|
101 |
+SIP_WARNING sip_warning |
|
102 |
+FIFO fifo |
|
103 |
+FIFO_MODE fifo_mode |
|
104 |
+SERVER_SIGNATURE server_signature |
|
105 |
+REPLY_TO_VIA reply_to_via |
|
98 | 106 |
|
99 | 107 |
LOADMODULE loadmodule |
100 | 108 |
MODPARAM modparam |
... | ... |
@@ -148,6 +156,7 @@ EAT_ABLE [\ \t\b\r] |
148 | 156 |
<INITIAL>{ISFLAGSET} { count(); yylval.strval=yytext; return ISFLAGSET; } |
149 | 157 |
<INITIAL>{LEN_GT} { count(); yylval.strval=yytext; return LEN_GT; } |
150 | 158 |
<INITIAL>{ROUTE} { count(); yylval.strval=yytext; return ROUTE; } |
159 |
+<INITIAL>{REPLY_ROUTE} { count(); yylval.strval=yytext; return REPLY_ROUTE; } |
|
151 | 160 |
<INITIAL>{EXEC} { count(); yylval.strval=yytext; return EXEC; } |
152 | 161 |
<INITIAL>{SET_HOST} { count(); yylval.strval=yytext; return SET_HOST; } |
153 | 162 |
<INITIAL>{SET_HOSTPORT} { count(); yylval.strval=yytext; return SET_HOSTPORT; } |
... | ... |
@@ -155,8 +164,10 @@ EAT_ABLE [\ \t\b\r] |
155 | 164 |
<INITIAL>{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; } |
156 | 165 |
<INITIAL>{SET_PORT} { count(); yylval.strval=yytext; return SET_PORT; } |
157 | 166 |
<INITIAL>{SET_URI} { count(); yylval.strval=yytext; return SET_URI; } |
167 |
+<INITIAL>{REVERT_URI} { count(); yylval.strval=yytext; return REVERT_URI; } |
|
158 | 168 |
<INITIAL>{PREFIX} { count(); yylval.strval=yytext; return PREFIX; } |
159 | 169 |
<INITIAL>{STRIP} { count(); yylval.strval=yytext; return STRIP; } |
170 |
+<INITIAL>{APPEND_BRANCH} { count(); yylval.strval=yytext; return APPEND_BRANCH; } |
|
160 | 171 |
<INITIAL>{IF} { count(); yylval.strval=yytext; return IF; } |
161 | 172 |
<INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; } |
162 | 173 |
|
... | ... |
@@ -181,7 +192,12 @@ EAT_ABLE [\ \t\b\r] |
181 | 192 |
<INITIAL>{MAXBUFFER} { count(); yylval.strval=yytext; return MAXBUFFER; } |
182 | 193 |
<INITIAL>{CHILDREN} { count(); yylval.strval=yytext; return CHILDREN; } |
183 | 194 |
<INITIAL>{CHECK_VIA} { count(); yylval.strval=yytext; return CHECK_VIA; } |
184 |
-<INITIAL>{LOOP_CHECKS} { count(); yylval.strval=yytext; return LOOP_CHECKS; } |
|
195 |
+<INITIAL>{SYN_BRANCH} { count(); yylval.strval=yytext; return SYN_BRANCH; } |
|
196 |
+<INITIAL>{SIP_WARNING} { count(); yylval.strval=yytext; return SIP_WARNING; } |
|
197 |
+<INITIAL>{FIFO} { count(); yylval.strval=yytext; return FIFO; } |
|
198 |
+<INITIAL>{FIFO_MODE} { count(); yylval.strval=yytext; return FIFO_MODE; } |
|
199 |
+<INITIAL>{SERVER_SIGNATURE} { count(); yylval.strval=yytext; return SERVER_SIGNATURE; } |
|
200 |
+<INITIAL>{REPLY_TO_VIA} { count(); yylval.strval=yytext; return REPLY_TO_VIA; } |
|
185 | 201 |
<INITIAL>{LOADMODULE} { count(); yylval.strval=yytext; return LOADMODULE; } |
186 | 202 |
<INITIAL>{MODPARAM} { count(); yylval.strval=yytext; return MODPARAM; } |
187 | 203 |
|
... | ... |
@@ -56,15 +56,18 @@ void* f_tmp; |
56 | 56 |
%token LOG_TOK |
57 | 57 |
%token ERROR |
58 | 58 |
%token ROUTE |
59 |
+%token REPLY_ROUTE |
|
59 | 60 |
%token EXEC |
60 | 61 |
%token SET_HOST |
61 | 62 |
%token SET_HOSTPORT |
62 | 63 |
%token PREFIX |
63 | 64 |
%token STRIP |
65 |
+%token APPEND_BRANCH |
|
64 | 66 |
%token SET_USER |
65 | 67 |
%token SET_USERPASS |
66 | 68 |
%token SET_PORT |
67 | 69 |
%token SET_URI |
70 |
+%token REVERT_URI |
|
68 | 71 |
%token IF |
69 | 72 |
%token ELSE |
70 | 73 |
%token URIHOST |
... | ... |
@@ -90,7 +93,12 @@ void* f_tmp; |
90 | 93 |
%token STAT |
91 | 94 |
%token CHILDREN |
92 | 95 |
%token CHECK_VIA |
93 |
-%token LOOP_CHECKS |
|
96 |
+%token SYN_BRANCH |
|
97 |
+%token SIP_WARNING |
|
98 |
+%token FIFO |
|
99 |
+%token FIFO_MODE |
|
100 |
+%token SERVER_SIGNATURE |
|
101 |
+%token REPLY_TO_VIA |
|
94 | 102 |
%token LOADMODULE |
95 | 103 |
%token MODPARAM |
96 | 104 |
%token MAXBUFFER |
... | ... |
@@ -151,6 +159,7 @@ statements: statements statement {} |
151 | 159 |
statement: assign_stm |
152 | 160 |
| module_stm |
153 | 161 |
| route_stm |
162 |
+ | reply_route_stm |
|
154 | 163 |
| CR /* null statement*/ |
155 | 164 |
; |
156 | 165 |
|
... | ... |
@@ -180,8 +189,18 @@ assign_stm: DEBUG EQUAL NUMBER { debug=$3; } |
180 | 189 |
| CHILDREN EQUAL error { yyerror("number expected"); } |
181 | 190 |
| CHECK_VIA EQUAL NUMBER { check_via=$3; } |
182 | 191 |
| CHECK_VIA EQUAL error { yyerror("boolean value expected"); } |
183 |
- | LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; } |
|
184 |
- | LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); } |
|
192 |
+ | SYN_BRANCH EQUAL NUMBER { syn_branch=$3; } |
|
193 |
+ | SYN_BRANCH EQUAL error { yyerror("boolean value expected"); } |
|
194 |
+ | SIP_WARNING EQUAL NUMBER { sip_warning=$3; } |
|
195 |
+ | SIP_WARNING EQUAL error { yyerror("boolean value expected"); } |
|
196 |
+ | FIFO EQUAL STRING { fifo=$3; } |
|
197 |
+ | FIFO EQUAL error { yyerror("string value expected"); } |
|
198 |
+ | FIFO_MODE EQUAL NUMBER { fifo_mode=$3; } |
|
199 |
+ | FIFO_MODE EQUAL NUMBER { yyerror("int value expected"); } |
|
200 |
+ | SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; } |
|
201 |
+ | SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); } |
|
202 |
+ | REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; } |
|
203 |
+ | REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); } |
|
185 | 204 |
| LISTEN EQUAL ip { |
186 | 205 |
if (sock_no< MAX_LISTEN){ |
187 | 206 |
tmp=ip_addr2a($3); |
... | ... |
@@ -347,6 +366,17 @@ route_stm: ROUTE LBRACE actions RBRACE { push($3, &rlist[DEFAULT_RT]); } |
347 | 366 |
} |
348 | 367 |
| ROUTE error { yyerror("invalid route statement"); } |
349 | 368 |
; |
369 |
+ |
|
370 |
+reply_route_stm: REPLY_ROUTE LBRACK NUMBER RBRACK LBRACE actions RBRACE { |
|
371 |
+ if (($3<REPLY_RT_NO)&&($3>=1)){ |
|
372 |
+ push($6, &reply_rlist[$3]); |
|
373 |
+ } else { |
|
374 |
+ yyerror("invalid reply routing" |
|
375 |
+ "table number"); |
|
376 |
+ YYABORT; } |
|
377 |
+ } |
|
378 |
+ | REPLY_ROUTE error { yyerror("invalid reply_route statement"); } |
|
379 |
+ ; |
|
350 | 380 |
/* |
351 | 381 |
rules: rules rule { push($2, &$1); $$=$1; } |
352 | 382 |
| rule {$$=$1; } |
... | ... |
@@ -685,6 +715,12 @@ cmd: FORWARD LPAREN host RPAREN { $$=mk_action( FORWARD_T, |
685 | 715 |
| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
686 | 716 |
"number expected"); } |
687 | 717 |
|
718 |
+ | APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T, |
|
719 |
+ STRING_ST, 0, $3, 0) ; } |
|
720 |
+ | APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T, |
|
721 |
+ STRING_ST, 0, 0, 0 ) ; } |
|
722 |
+ | APPEND_BRANCH { $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; } |
|
723 |
+ |
|
688 | 724 |
| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, |
689 | 725 |
STRING_ST, 0, $3, 0); } |
690 | 726 |
| SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); } |
... | ... |
@@ -710,6 +746,8 @@ cmd: FORWARD LPAREN host RPAREN { $$=mk_action( FORWARD_T, |
710 | 746 |
| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); } |
711 | 747 |
| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, " |
712 | 748 |
"string expected"); } |
749 |
+ | REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); } |
|
750 |
+ | REVERT_URI { $$=mk_action( REVERT_URI_T, 0,0,0,0); } |
|
713 | 751 |
| ID LPAREN RPAREN { f_tmp=(void*)find_export($1, 0); |
714 | 752 |
if (f_tmp==0){ |
715 | 753 |
yyerror("unknown command, missing" |
... | ... |
@@ -22,6 +22,7 @@ |
22 | 22 |
#define CHILD_NO 8 |
23 | 23 |
|
24 | 24 |
#define RT_NO 10 /* routing tables number */ |
25 |
+#define REPLY_RT_NO 10 /* reply routing tables number */ |
|
25 | 26 |
#define DEFAULT_RT 0 /* default routing table */ |
26 | 27 |
|
27 | 28 |
#define MAX_REC_LEV 100 /* maximum number of recursive calls */ |
... | ... |
@@ -46,8 +47,8 @@ |
46 | 47 |
|
47 | 48 |
#define MAX_WARNING_LEN 256 |
48 | 49 |
|
49 |
-#define MY_BRANCH ";branch=0" |
|
50 |
-#define MY_BRANCH_LEN 9 |
|
50 |
+#define MY_BRANCH ";branch=" |
|
51 |
+#define MY_BRANCH_LEN 8 |
|
51 | 52 |
|
52 | 53 |
|
53 | 54 |
#define MAX_PORT_LEN 7 /* ':' + max 5 letters + \0 */ |
... | ... |
@@ -88,8 +89,16 @@ |
88 | 89 |
#define MAX_VIA_LINE_SIZE 240 |
89 | 90 |
#define MAX_RECEIVED_SIZE 57 |
90 | 91 |
|
91 |
-/* maximum number of processes is constrained by capacity of |
|
92 |
- process bitmaps */ |
|
93 |
-#define MAX_PROCESSES (sizeof( process_bm_t) * 8 ) |
|
92 |
+/* maximum number of branches per transaction */ |
|
93 |
+#define MAX_BRANCHES 4 |
|
94 | 94 |
|
95 |
+/* maximum length of a FIFO server command */ |
|
96 |
+#define MAX_FIFO_COMMAND 512 |
|
97 |
+ |
|
98 |
+/* buffer dimensions for FIFO server */ |
|
99 |
+#define MAX_CONSUME_BUFFER 1024 |
|
100 |
+/* where reply pipes may be opened */ |
|
101 |
+#define FIFO_DIR "/tmp/" |
|
102 |
+/* max length of the text of fifo 'print' command */ |
|
103 |
+#define MAX_PRINT_TEXT 256 |
|
95 | 104 |
#endif |
96 | 105 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,87 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ * destination set |
|
5 |
+ */ |
|
6 |
+ |
|
7 |
+#include <string.h> |
|
8 |
+ |
|
9 |
+#include "dprint.h" |
|
10 |
+#include "config.h" |
|
11 |
+#include "parser/parser_f.h" |
|
12 |
+#include "parser/msg_parser.h" |
|
13 |
+#include "ut.h" |
|
14 |
+#include "hash_func.h" |
|
15 |
+#include "dset.h" |
|
16 |
+ |
|
17 |
+ |
|
18 |
+ |
|
19 |
+/* where we store URIs of additional transaction branches |
|
20 |
+ (-1 because of the default branch, #0) |
|
21 |
+*/ |
|
22 |
+static struct branch branches[ MAX_BRANCHES - 1 ]; |
|
23 |
+/* how many of them we have */ |
|
24 |
+static unsigned int nr_branches=0; |
|
25 |
+/* branch iterator */ |
|
26 |
+static int branch_iterator=0; |
|
27 |
+ |
|
28 |
+void init_branch_iterator(void) |
|
29 |
+{ |
|
30 |
+ branch_iterator=0; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+char *next_branch( int *len ) |
|
34 |
+{ |
|
35 |
+ unsigned int i; |
|
36 |
+ |
|
37 |
+ i=branch_iterator; |
|
38 |
+ if (i<nr_branches) { |
|
39 |
+ branch_iterator++; |
|
40 |
+ *len=branches[i].len; |
|
41 |
+ return branches[i].uri; |
|
42 |
+ } else { |
|
43 |
+ *len=0; |
|
44 |
+ return 0; |
|
45 |
+ } |
|
46 |
+} |
|
47 |
+ |
|
48 |
+void clear_branches() |
|
49 |
+{ |
|
50 |
+ nr_branches=0; |
|
51 |
+} |
|
52 |
+ |
|
53 |
+/* add a new branch to current transaction */ |
|
54 |
+int append_branch( struct sip_msg *msg, char *uri, int uri_len ) |
|
55 |
+{ |
|
56 |
+ /* if we have already set up the maximum number |
|
57 |
+ of branches, don't try new ones */ |
|
58 |
+ if (nr_branches==MAX_BRANCHES-1) { |
|
59 |
+ LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n"); |
|
60 |
+ return -1; |
|
61 |
+ } |
|
62 |
+ |
|
63 |
+ if (uri_len>MAX_URI_SIZE-1) { |
|
64 |
+ LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n", |
|
65 |
+ uri_len, uri ); |
|
66 |
+ return -1; |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ /* if not parameterized, take current uri */ |
|
70 |
+ if (uri==0) { |
|
71 |
+ if (msg->new_uri.s) { |
|
72 |
+ uri=msg->new_uri.s; |
|
73 |
+ uri_len=msg->new_uri.len; |
|
74 |
+ } else { |
|
75 |
+ uri=msg->first_line.u.request.uri.s; |
|
76 |
+ uri_len=msg->first_line.u.request.uri.len; |
|
77 |
+ } |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ memcpy( branches[nr_branches].uri, uri, uri_len ); |
|
81 |
+ /* be safe -- add zero termination */ |
|
82 |
+ branches[nr_branches].uri[uri_len]=0; |
|
83 |
+ branches[nr_branches].len=uri_len; |
|
84 |
+ |
|
85 |
+ nr_branches++; |
|
86 |
+ return 1; |
|
87 |
+} |
0 | 88 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,29 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ */ |
|
4 |
+ |
|
5 |
+#ifndef _T_FORKS_H |
|
6 |
+#define _T_FORKS_H |
|
7 |
+ |
|
8 |
+#include "config.h" |
|
9 |
+ |
|
10 |
+struct branch |
|
11 |
+{ |
|
12 |
+ char uri[MAX_URI_SIZE]; |
|
13 |
+ unsigned int len; |
|
14 |
+}; |
|
15 |
+ |
|
16 |
+struct sip_msg; |
|
17 |
+ |
|
18 |
+/* |
|
19 |
+typedef int (*tfork_f)( struct sip_msg *msg, char *uri, int uri_len ); |
|
20 |
+*/ |
|
21 |
+ |
|
22 |
+/* add a new branch to current transaction */ |
|
23 |
+int append_branch( struct sip_msg *msg, char *uri, int uri_len ); |
|
24 |
+/* iterate through list of new transaction branches */ |
|
25 |
+void init_branch_iterator(); |
|
26 |
+char *next_branch( int *len ); |
|
27 |
+void clear_branches(); |
|
28 |
+ |
|
29 |
+#endif |
... | ... |
@@ -5,6 +5,9 @@ |
5 | 5 |
|
6 | 6 |
#include <stdio.h> |
7 | 7 |
#include "error.h" |
8 |
+#include "str.h" |
|
9 |
+#include "parser/msg_parser.h" |
|
10 |
+#include "mem/mem.h" |
|
8 | 11 |
|
9 | 12 |
/* current function's error; */ |
10 | 13 |
int ser_error=-1; |
... | ... |
@@ -43,6 +46,10 @@ int err2reason_phrase( |
43 | 46 |
error_txt="Regretfuly, we were not able to process the URI"; |
44 | 47 |
*sip_error=-ser_error; |
45 | 48 |
break; |
49 |
+ case E_BAD_TUPEL: |
|
50 |
+ error_txt="Transaction tupel incomplete"; |
|
51 |
+ *sip_error=-E_BAD_REQ; |
|
52 |
+ break; |
|
46 | 53 |
default: |
47 | 54 |
error_txt="I'm terribly sorry, server error occured"; |
48 | 55 |
*sip_error=500; |
... | ... |
@@ -51,3 +58,104 @@ int err2reason_phrase( |
51 | 58 |
return snprintf( phrase, etl, "%s (%d/%s)", error_txt, |
52 | 59 |
-ser_error, signature ); |
53 | 60 |
} |
61 |
+ |
|
62 |
+char *error_text( int code ) |
|
63 |
+{ |
|
64 |
+ switch(code) { |
|
65 |
+ |
|
66 |
+ case 100: return "Trying"; |
|
67 |
+ case 180: return "Ringing"; |
|
68 |
+ case 181: return "Call is Being Forwarded"; |
|
69 |
+ case 182: return "Queued"; |
|
70 |
+ case 183: return "Session Progress"; |
|
71 |
+ |
|
72 |
+ case 200: return "OK"; |
|
73 |
+ |
|
74 |
+ case 300: return "Multiple Choices"; |
|
75 |
+ case 301: return "Moved Permanently"; |
|
76 |
+ case 302: return "Moved Temporarily"; |
|
77 |
+ case 305: return "Use Proxy"; |
|
78 |
+ case 380: return "Alternative Service"; |
|
79 |
+ |
|
80 |
+ case 400: return "Bad Request"; |
|
81 |
+ case 401: return "Unauthorized"; |
|
82 |
+ case 402: return "Payement Required"; |
|
83 |
+ case 403: return "Forbidden"; |
|
84 |
+ case 404: return "Not Found"; |
|
85 |
+ case 405: return "Method not Allowed"; |
|
86 |
+ case 406: return "Not Acceptable"; |
|
87 |
+ case 407: return "Proxy authentication Required"; |
|
88 |
+ case 408: return "Request Timeout"; |
|
89 |
+ case 410: return "Gone"; |
|
90 |
+ case 413: return "Request Entity Too Large"; |
|
91 |
+ case 414: return "Request-URI Too Long"; |
|
92 |
+ case 415: return "Unsupported Media Type"; |
|
93 |
+ case 416: return "Unsupported URI Scheme"; |
|
94 |
+ case 417: return "Bad Extension"; |
|
95 |
+ case 421: return "Extension Required"; |
|
96 |
+ case 423: return "Interval Too Brief"; |
|
97 |
+ case 480: return "Temporarily Unavailable"; |
|
98 |
+ case 481: return "Call/Transaction Does not Exist"; |
|
99 |
+ case 482: return "Loop Detected"; |
|
100 |
+ case 483: return "Too Many Hops"; |
|
101 |
+ case 484: return "Address Incomplete"; |
|
102 |
+ case 485: return "Ambigous"; |
|
103 |
+ case 486: return "Busy Here"; |
|
104 |
+ case 487: return "Request Terminated"; |
|
105 |
+ case 488: return "Not Acceptable Here"; |
|
106 |
+ case 491: return "Request Pending"; |
|
107 |
+ |
|
108 |
+ case 500: return "Server Internal Error"; |
|
109 |
+ case 501: return "Not Implemented"; |
|
110 |
+ case 502: return "Bad Gateway"; |
|
111 |
+ case 503: return "Service Unavailable"; |
|
112 |
+ case 504: return "Server Time-out"; |
|
113 |
+ case 505: return "Version not Supported"; |
|
114 |
+ case 513: return "Message Too Large"; |
|
115 |
+ |
|
116 |
+ case 600: return "Busy Everywhere"; |
|
117 |
+ case 603: return "Decline"; |
|
118 |
+ case 604: return "Does not Exist Anywhere"; |
|
119 |
+ case 606: return "Not Acceptable"; |
|
120 |
+ |
|
121 |
+ } |
|
122 |
+ |
|
123 |
+ if (code>=600) return "Global Failure"; |
|
124 |
+ else if (code>=500) return "Server Failure"; |
|
125 |
+ else if (code>=400) return "Request Failure"; |
|
126 |
+ else if (code>=300) return "Redirection"; |
|
127 |
+ else if (code>=200) return "Successful"; |
|
128 |
+ else if (code>=100) return "Provisional"; |
|
129 |
+ else return "Unspecified"; |
|
130 |
+} |
|
131 |
+ |
|
132 |
+void get_reply_status( str *status, struct sip_msg *reply, int code ) |
|
133 |
+{ |
|
134 |
+ str phrase; |
|
135 |
+ |
|
136 |
+ status->s=0; |
|
137 |
+ |
|
138 |
+ if (reply==0) { |
|
139 |
+ LOG(L_CRIT, "BUG: get_reply_status called with 0 msg\n"); |
|
140 |
+ return; |
|
141 |
+ } |
|
142 |
+ |
|
143 |
+ if (reply==FAKED_REPLY) { |
|
144 |
+ phrase.s=error_text(code); |
|
145 |
+ phrase.len=strlen(phrase.s); |
|
146 |
+ } else { |
|
147 |
+ phrase=reply->first_line.u.reply.reason; |
|
148 |
+ } |
|
149 |
+ status->len=phrase.len+3/*code*/+1/*space*/+1/*ZT*/; |
|
150 |
+ status->s=pkg_malloc(status->len); |
|
151 |
+ if (!status->s) { |
|
152 |
+ LOG(L_ERR, "ERROR: get_reply_status: no mem\n"); |
|
153 |
+ return; |
|
154 |
+ } |
|
155 |
+ status->s[3]=' '; |
|
156 |
+ status->s[2]='0'+code % 10; code=code/10; |
|
157 |
+ status->s[1]='0'+code% 10; code=code/10; |
|
158 |
+ status->s[0]='0'+code % 10; |
|
159 |
+ memcpy(&status->s[4], phrase.s, phrase.len); |
|
160 |
+ status->s[status->len-1]=0; |
|
161 |
+} |
... | ... |
@@ -12,6 +12,12 @@ |
12 | 12 |
#define E_BUG -5 |
13 | 13 |
#define E_CFG -6 |
14 | 14 |
#define E_NO_SOCKET -7 |
15 |
+/* unresolveable topmost Via */ |
|
16 |
+#define E_BAD_VIA -8 |
|
17 |
+/* incomplete transaction tupel */ |
|
18 |
+#define E_BAD_TUPEL -9 |
|
19 |
+/* script programming error */ |
|
20 |
+#define E_SCRIPT -10 |
|
15 | 21 |
|
16 | 22 |
#define E_SEND -477 |
17 | 23 |
/* unresolveable next-hop address */ |
... | ... |
@@ -23,12 +29,22 @@ |
23 | 29 |
|
24 | 30 |
#define MAX_REASON_LEN 128 |
25 | 31 |
|
32 |
+#include "str.h" |
|
33 |
+ |
|
26 | 34 |
/* processing status of the last command */ |
27 | 35 |
extern int ser_error; |
28 | 36 |
extern int prev_ser_error; |
29 | 37 |
|
38 |
+struct sip_msg; |
|
39 |
+ |
|
40 |
+/* ser error -> SIP error */ |
|
30 | 41 |
int err2reason_phrase( int ser_error, int *sip_error, |
31 | 42 |
char *phrase, int etl, char *signature ); |
32 | 43 |
|
44 |
+/* SIP error core -> SIP text */ |
|
45 |
+char *error_text( int code ); |
|
46 |
+ |
|
47 |
+/* return pkg_malloc-ed reply status in status->s */ |
|
48 |
+void get_reply_status( str *status, struct sip_msg *reply, int code ); |
|
33 | 49 |
|
34 | 50 |
#endif |
619 | 620 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,344 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ * simple UAC for things such as SUBSCRIBE or SMS gateway; |
|
5 |
+ * no authentication and other UAC features -- just send |
|
6 |
+ * a message, retransmit and await a reply; forking is not |
|
7 |
+ * supported during client generation, in all other places |
|
8 |
+ * it is -- adding it should be simple |
|
9 |
+ */ |
|
10 |
+ |
|
11 |
+#include <stdlib.h> |
|
12 |
+#include <sys/types.h> |
|
13 |
+#include <unistd.h> |
|
14 |
+#include <stdio.h> |
|
15 |
+#include <errno.h> |
|
16 |
+#include <sys/types.h> |
|
17 |
+#include <sys/stat.h> |
|
18 |
+#include <fcntl.h> |
|
19 |
+#include <signal.h> |
|
20 |
+#include <string.h> |
|
21 |
+#include "dprint.h" |
|
22 |
+#include "ut.h" |
|
23 |
+#include "error.h" |
|
24 |
+#include "config.h" |
|
25 |
+#include "globals.h" |
|
26 |
+#include "fifo_server.h" |
|
27 |
+#include "mem/mem.h" |
|
28 |
+ |
|
29 |
+/* FIFO server vars */ |
|
30 |
+char *fifo=0; /* FIFO name */ |
|
31 |
+int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; |
|
32 |
+pid_t fifo_pid; |
|
33 |
+/* file descriptors */ |
|
34 |
+static int fifo_read=0; |
|
35 |
+static int fifo_write=0; |
|
36 |
+static FILE *fifo_stream; |
|
37 |
+ |
|
38 |
+/* list of fifo command */ |
|
39 |
+static struct fifo_command *cmd_list=0; |
|
40 |
+ |
|
41 |
+static struct fifo_command *lookup_fifo_cmd( char *name ) |
|
42 |
+{ |
|
43 |
+ struct fifo_command *c; |
|
44 |
+ for(c=cmd_list; c; c=c->next) { |
|
45 |
+ if (strcasecmp(c->name, name)==0) return c; |
|
46 |
+ } |
|
47 |
+ return 0; |
|
48 |
+} |
|
49 |
+ |
|
50 |
+int register_fifo_cmd(fifo_cmd f, char *cmd_name, void *param) |
|
51 |
+{ |
|
52 |
+ struct fifo_command *new_cmd; |
|
53 |
+ |
|
54 |
+ if (lookup_fifo_cmd(cmd_name)) { |
|
55 |
+ LOG(L_ERR, "ERROR: register_fifo_cmd: attempt to register synonyms\n"); |
|
56 |
+ return E_BUG; |
|
57 |
+ } |
|
58 |
+ new_cmd=malloc(sizeof(struct fifo_command)); |
|
59 |
+ if (new_cmd==0) { |
|
60 |
+ LOG(L_ERR, "ERROR: register_fifo_cmd: out of mem\n"); |
|
61 |
+ return E_OUT_OF_MEM; |
|
62 |
+ } |
|
63 |
+ new_cmd->f=f; |
|
64 |
+ new_cmd->name=cmd_name; |
|
65 |
+ new_cmd->param=param; |
|
66 |
+ |
|
67 |
+ new_cmd->next=cmd_list; |
|
68 |
+ cmd_list=new_cmd; |
|
69 |
+ |
|
70 |
+ return 1; |
|
71 |
+} |
|
72 |
+ |
|
73 |
+ |
|
74 |
+int read_line( char *b, int max, FILE *stream, int *read ) |
|
75 |
+{ |
|
76 |
+ int len; |
|
77 |
+ if (fgets(b, max, stream)==NULL) { |
|
78 |
+ LOG(L_ERR, "ERROR: fifo_server fgets failed: %s\n", |
|
79 |
+ strerror(errno)); |
|
80 |
+ kill(0, SIGTERM); |
|
81 |
+ } |
|
82 |
+ /* if we did not read whole line, our buffer is too small |
|
83 |
+ and we cannot process the request; consume the remainder of |
|
84 |
+ request |
|
85 |
+ */ |
|
86 |
+ len=strlen(b); |
|
87 |
+ if (len && !(b[len-1]=='\n' || b[len-1]=='\r')) { |
|
88 |
+ LOG(L_ERR, "ERROR: read_line: request line too long\n"); |
|
89 |
+ return 0; |
|
90 |
+ } |
|
91 |
+ /* trim from right */ |
|
92 |
+ while(len) { |
|
93 |
+ if(b[len-1]=='\n' || b[len-1]=='\r' |
|
94 |
+ || b[len-1]==' ' || b[len-1]=='\t' ) { |
|
95 |
+ len--; |
|
96 |
+ b[len]=0; |
|
97 |
+ } else break; |
|
98 |
+ } |
|
99 |
+ *read=len; |
|
100 |
+ return 1; |
|
101 |
+} |
|
102 |
+ |
|
103 |
+static void consume_request( FILE *stream ) |
|
104 |
+{ |
|
105 |
+ int len; |
|
106 |
+ char buffer[MAX_CONSUME_BUFFER]; |
|
107 |
+ |
|
108 |
+ while(!read_line(buffer, MAX_CONSUME_BUFFER, stream, &len)); |
|
109 |
+ |
|
110 |
+#ifdef _OBSOLETED |
|
111 |
+ int eol_count; |
|
112 |
+ |
|
113 |
+ eol_count=0; |
|
114 |
+ |
|
115 |
+ /* each request must be terminated by two EoLs */ |
|
116 |
+ while(eol_count!=2) { |
|
117 |
+ /* read until EoL is encountered */ |
|
118 |
+ while(!read_line(buffer, MAX_CONSUME_BUFFER, stream, &len)); |
|
119 |
+ eol_count=len==0?eol_count+1:1; |
|
120 |
+ } |
|
121 |
+#endif |
|
122 |
+} |
|
123 |
+ |
|
124 |
+int read_eol( FILE *stream ) |
|
125 |
+{ |
|
126 |
+ int len; |
|
127 |
+ char buffer[MAX_CONSUME_BUFFER]; |
|
128 |
+ if (!read_line(buffer, MAX_CONSUME_BUFFER, stream, &len) || len!=0) { |
|
129 |
+ LOG(L_ERR, "ERROR: read_eol: EOL expected: %.10s...\n", |
|
130 |
+ buffer ); |
|
131 |
+ return 0; |
|
132 |
+ } |
|
133 |
+ return 1; |
|
134 |
+} |
|
135 |
+ |
|
136 |
+int read_line_set(char *buf, int max_len, FILE *fifo, int *len) |
|
137 |
+{ |
|
138 |
+ int set_len; |
|
139 |
+ char *c; |
|
140 |
+ int line_len; |
|
141 |
+ |
|
142 |
+ c=buf;set_len=0; |
|
143 |
+ while(1) { |
|
144 |
+ if (!read_line(c,max_len,fifo,&line_len)) { |
|
145 |
+ LOG(L_ERR, "ERROR: fifo_server: line expected\n"); |
|
146 |
+ return 0; |
|
147 |
+ } |
|
148 |
+ /* end encountered ... return */ |
|
149 |
+ if (line_len==0) { |
|
150 |
+ *len=set_len; |
|
151 |
+ return 1; |
|
152 |
+ } |
|
153 |
+ max_len-=line_len; c+=line_len; set_len+=line_len; |
|
154 |
+ if (max_len<CRLF_LEN) { |
|
155 |
+ LOG(L_ERR, "ERROR: fifo_server: no place for CRLF\n"); |
|
156 |
+ return 0; |
|
157 |
+ } |
|
158 |
+ memcpy(c, CRLF, CRLF_LEN); |
|
159 |
+ max_len-=CRLF_LEN; c+=CRLF_LEN; set_len+=CRLF_LEN; |
|
160 |
+ } |
|
161 |
+} |
|
162 |
+ |
|
163 |
+static char *trim_filename( char * file ) |
|
164 |
+{ |
|
165 |
+ int prefix_len, fn_len; |
|
166 |
+ char *new_fn; |
|
167 |
+ |
|
168 |
+ /* we only allow files in "/tmp" -- any directory |
|
169 |
+ changes are not welcome |
|
170 |
+ */ |
|
171 |
+ if (strchr(file,'.') || strchr(file,'/') |
|
172 |
+ || strchr(file, '\\')) { |
|
173 |
+ LOG(L_ERR, "ERROR: trim_filename: forbidden filename: %s\n" |
|
174 |
+ , file); |
|
175 |
+ return 0; |
|
176 |
+ } |
|
177 |
+ prefix_len=strlen(FIFO_DIR); fn_len=strlen(file); |
|
178 |
+ new_fn=pkg_malloc(prefix_len+fn_len+1); |
|
179 |
+ if (new_fn==0) { |
|
180 |
+ LOG(L_ERR, "ERROR: trim_filename: no mem\n"); |
|
181 |
+ return 0; |
|
182 |
+ } |
|
183 |
+ |
|
184 |
+ memcpy(new_fn, FIFO_DIR, prefix_len); |
|
185 |
+ memcpy(new_fn+prefix_len, file, fn_len ); |
|
186 |
+ new_fn[prefix_len+fn_len]=0; |
|
187 |
+ |
|
188 |
+ return new_fn; |
|
189 |
+} |
|
190 |
+ |
|
191 |
+static void fifo_server(FILE *fifo_stream) |
|
192 |
+{ |
|
193 |
+ char buf[MAX_FIFO_COMMAND]; |
|
194 |
+ int line_len; |
|
195 |
+ char *file_sep, *command, *file; |
|
196 |
+ struct fifo_command *f; |
|
197 |
+ |
|
198 |
+ file_sep=command=file=0; |
|
199 |
+ |
|
200 |
+ while(1) { |
|
201 |
+ |
|
202 |
+ /* commands must look this way ':<command>:[filename]' */ |
|
203 |
+ if (!read_line(buf, MAX_FIFO_COMMAND, fifo_stream, &line_len)) { |
|
204 |
+ /* line breaking must have failed -- consume the rest |
|
205 |
+ and proceed to a new request |
|
206 |
+ */ |
|
207 |
+ LOG(L_ERR, "ERROR: fifo_server: command expected\n"); |
|
208 |
+ goto consume; |
|
209 |
+ } |
|
210 |
+ if (line_len==0) { |
|
211 |
+ LOG(L_ERR, "ERROR: fifo_server: command empty\n"); |
|
212 |
+ continue; |
|
213 |
+ } |
|
214 |
+ if (line_len<3) { |
|
215 |
+ LOG(L_ERR, "ERROR: fifo_server: command must have at least 3 chars\n"); |
|
216 |
+ goto consume; |
|
217 |
+ } |
|
218 |
+ if (*buf!=CMD_SEPARATOR) { |
|
219 |
+ LOG(L_ERR, "ERROR: fifo_server: command must start with %c\n", |
|
220 |
+ CMD_SEPARATOR); |
|
221 |
+ goto consume; |
|
222 |
+ } |
|
223 |
+ command=buf+1; |
|
224 |
+ file_sep=strchr(command, CMD_SEPARATOR ); |
|
225 |
+ if (file_sep==NULL) { |
|
226 |
+ LOG(L_ERR, "ERROR: fifo_server: file separator missing\n"); |
|
227 |
+ goto consume; |
|
228 |
+ } |
|
229 |
+ if (file_sep==command) { |
|
230 |
+ LOG(L_ERR, "ERROR: fifo_server: empty command\n"); |
|
231 |
+ goto consume; |
|
232 |
+ } |
|
233 |
+ if (*(file_sep+1)==0) file=NULL; |
|
234 |
+ else { |
|
235 |
+ file=file_sep+1; |
|
236 |
+ file=trim_filename(file); |
|
237 |
+ if (file==0) { |
|
238 |
+ LOG(L_ERR, "ERROR: fifo_server: trimming filename\n"); |
|
239 |
+ goto consume; |
|
240 |
+ } |
|
241 |
+ } |
|
242 |
+ /* make command zero-terminated */ |
|
243 |
+ *file_sep=0; |
|
244 |
+ |
|
245 |
+ f=lookup_fifo_cmd( command ); |
|
246 |
+ if (f==0) { |
|
247 |
+ LOG(L_ERR, "ERROR: fifo_server: command %s is not available\n", |
|
248 |
+ command); |
|
249 |
+ goto consume; |
|
250 |
+ } |
|
251 |
+ if (f->f(fifo_stream, file)<0) { |
|
252 |
+ LOG(L_ERR, "ERROR: fifo_server: command (%s) " |
|
253 |
+ "processing failed\n", command ); |
|
254 |
+ goto consume; |
|
255 |
+ } |
|
256 |
+ |
|
257 |
+consume: |
|
258 |
+ if (file) { pkg_free(file); file=0;} |
|
259 |
+ consume_request(fifo_stream); |
|
260 |
+ } |
|
261 |
+} |
|
262 |
+ |
|
263 |
+int open_fifo_server() |
|
264 |
+{ |
|
265 |
+ if (fifo==NULL) { |
|
266 |
+ DBG("TM: open_uac_fifo: no fifo will be opened\n"); |
|
267 |
+ /* everything is ok, we just do not want to start */ |
|
268 |
+ return 1; |
|
269 |
+ } |
|
270 |
+ DBG("TM: open_uac_fifo: opening fifo...\n"); |
|
271 |
+ if ((mkfifo(fifo, fifo_mode)<0) && (errno!=EEXIST)) { |
|
272 |
+ LOG(L_ERR, "ERROR: open_fifo_server; can't create FIFO: %s\n", |
|
273 |
+ strerror(errno)); |
|
274 |
+ return -1; |
|
275 |
+ } |
|
276 |
+ process_no++; |
|
277 |
+ fifo_pid=fork(); |
|
278 |
+ if (fifo_pid<0) { |
|
279 |
+ LOG(L_ERR, "ERROR: open_fifo_server: failure to fork: %s\n", |
|
280 |
+ strerror(errno)); |
|
281 |
+ return -1; |
|
282 |
+ } |
|
283 |
+ if (fifo_pid==0) { /* child == FIFO server */ |
|
284 |
+ LOG(L_INFO, "INFO: fifo process starting: %d\n", getpid()); |
|
285 |
+ fifo_read=open(fifo, O_RDONLY, 0); |
|
286 |
+ if (fifo_read<0) { |
|
287 |
+ LOG(L_ERR, "SER: open_uac_fifo: fifo_read did not open: %s\n", |
|
288 |
+ strerror(errno)); |
|
289 |
+ return -1; |
|
290 |
+ } |
|
291 |
+ fifo_stream=fdopen(fifo_read, "r" ); |
|
292 |
+ if (fifo_stream==NULL) { |
|
293 |
+ LOG(L_ERR, "SER: open_uac_fifo: fdopen failed: %s\n", |
|
294 |
+ strerror(errno)); |
|
295 |
+ return -1; |
|
296 |
+ } |
|
297 |
+ LOG(L_INFO, "SER: open_uac_fifo: fifo server up...\n"); |
|
298 |
+ fifo_server( fifo_stream ); /* never retruns */ |
|
299 |
+ } |
|
300 |
+ /* dad process */ |
|
301 |
+ pids[process_no]=fifo_pid; |
|
302 |
+ /* make sure the read fifo will not close */ |
|
303 |
+ fifo_write=open(fifo, O_WRONLY, 0); |
|
304 |
+ if (fifo_write<0) { |
|
305 |
+ LOG(L_ERR, "SER: open_uac_fifo: fifo_write did not open: %s\n", |
|
306 |
+ strerror(errno)); |
|
307 |
+ return -1; |
|
308 |
+ } |
|
309 |
+ return 1; |
|
310 |
+} |
|
311 |
+ |
|
312 |
+/* diagnostic and hello-world FIFO command */ |
|
313 |
+int print_fifo_cmd( FILE *stream, char *response_file ) |
|
314 |
+{ |
|
315 |
+ char text[MAX_PRINT_TEXT]; |
|
316 |
+ int text_len; |
|
317 |
+ int file; |
|
318 |
+ |
|
319 |
+ /* expect one line which will be printed out */ |
|
320 |
+ if (!read_line(text, MAX_PRINT_TEXT, stream, &text_len)) { |
|
321 |
+ LOG(L_ERR, "ERROR: print_fifo_cmd: too big text\n"); |
|
322 |
+ return -1; |
|
323 |
+ } |
|
324 |
+ /* now the work begins */ |
|
325 |
+ if (response_file) { |
|
326 |
+ file=open( response_file , O_WRONLY); |
|
327 |
+ if (file<0) { |
|
328 |
+ LOG(L_ERR, "ERROR: print_fifo_cmd: open error (%s): %s\n", |
|
329 |
+ response_file, strerror(errno)); |
|
330 |
+ return -1; |
|
331 |
+ } |
|
332 |
+ if (write(file, text,text_len)<0) { |
|
333 |
+ LOG(L_ERR, "ERROR: print_fifo_cmd: write error: %s\n", |
|
334 |
+ strerror(errno)); |
|
335 |
+ close(file); |
|
336 |
+ return -1; |
|
337 |
+ } |
|
338 |
+ close(file); |
|
339 |
+ } else { |
|
340 |
+ LOG(L_INFO, "INFO: print_fifo_cmd: %.*s\n", |
|
341 |
+ text_len, text ); |
|
342 |
+ } |
|
343 |
+ return 1; |
|
344 |
+} |
0 | 345 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,34 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ */ |
|
5 |
+ |
|
6 |
+#ifndef _FIFO_SERVER_H |
|
7 |
+#define _FIFO_SERVER_H |
|
8 |
+ |
|
9 |
+#include <stdio.h> |
|
10 |
+ |
|
11 |
+#define CMD_SEPARATOR ':' |
|
12 |
+ |
|
13 |
+typedef int (fifo_cmd)( FILE *fifo_stream, char *response_file ); |
|
14 |
+ |
|
15 |
+struct fifo_command{ |
|
16 |
+ fifo_cmd *f; |
|
17 |
+ struct fifo_command *next; |
|
18 |
+ void *param; |
|
19 |
+ char *name; |
|
20 |
+}; |
|
21 |
+ |
|
22 |
+int register_fifo_cmd(fifo_cmd f, char *cmd_name, void *param); |
|
23 |
+ |
|
24 |
+/* read a single EoL-terminated line from fifo */ |
|
25 |
+int read_line( char *b, int max, FILE *stream, int *read ); |
|
26 |
+/* consume EoL from fifo */ |
|
27 |
+int read_eol( FILE *stream ); |
|
28 |
+/* consume a set of EoL-terminated lines terminated by an additional EoL */ |
|
29 |
+int read_line_set(char *buf, int max_len, FILE *fifo, int *len); |
|
30 |
+ |
|
31 |
+int open_fifo_server(); |
|
32 |
+ |
|
33 |
+int print_fifo_cmd( FILE *stream, char *response_file ); |
|
34 |
+#endif |
... | ... |
@@ -16,12 +16,12 @@ int setflag( struct sip_msg* msg, flag_t flag ) { |
16 | 16 |
} |
17 | 17 |
|
18 | 18 |
int resetflag( struct sip_msg* msg, flag_t flag ) { |
19 |
- msg->flags &= ~ flag; |
|
19 |
+ msg->flags &= ~ (1 << flag); |
|
20 | 20 |
return 1; |
21 | 21 |
} |
22 | 22 |
|
23 | 23 |
int isflagset( struct sip_msg* msg, flag_t flag ) { |
24 |
- return msg->flags & (1<<flag) ? 1 : -1; |
|
24 |
+ return (msg->flags & (1<<flag)) ? 1 : -1; |
|
25 | 25 |
} |
26 | 26 |
|
27 | 27 |
int flag_in_range( flag_t flag ) { |
... | ... |
@@ -13,6 +13,7 @@ |
13 | 13 |
#include <arpa/inet.h> |
14 | 14 |
|
15 | 15 |
#include "forward.h" |
16 |
+#include "hash_func.h" |
|
16 | 17 |
#include "config.h" |
17 | 18 |
#include "parser/msg_parser.h" |
18 | 19 |
#include "route.h" |
... | ... |
@@ -67,6 +68,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
67 | 68 |
char* buf; |
68 | 69 |
union sockaddr_union* to; |
69 | 70 |
struct socket_info* send_sock; |
71 |
+ char md5[MD5_LEN]; |
|
70 | 72 |
|
71 | 73 |
to=0; |
72 | 74 |
buf=0; |
... | ... |
@@ -98,13 +100,39 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
98 | 100 |
LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d " |
99 | 101 |
"no coresponding listening socket\n", to->s.sa_family); |
100 | 102 |
ser_error=E_NO_SOCKET; |
101 |
- goto error; |
|
103 |
+ goto error1; |
|
102 | 104 |
} |
103 |
- |
|
105 |
+ |
|
106 |
+ /* calculate branch for outbound request; if syn_branch is turned off, |
|
107 |
+ calculate is from transaction key, i.e., as an md5 of From/To/CallID/ |
|
108 |
+ CSeq exactly the same way as TM does; good for reboot -- than messages |
|
109 |
+ belonging to transaction lost due to reboot will still be forwarded |
|
110 |
+ with the same branch parameter and will be match-able downstream |
|
111 |
+ |
|
112 |
+ if it is turned on, we don't care about reboot; we simply put a simple |
|
113 |
+ value in there; better for performance |
|
114 |
+ */ |
|
115 |
+ |
|
116 |
+ if (syn_branch ) { |
|
117 |
+ *msg->add_to_branch_s='0'; |
|
118 |
+ msg->add_to_branch_len=1; |
|
119 |
+ } else { |
|
120 |
+ if (!char_msg_val( msg, md5 )) { /* parses transaction key */ |
|
121 |
+ LOG(L_ERR, "ERROR: forward_request: char_msg_val failed\n"); |
|
122 |
+ goto error1; |
|
123 |
+ } |
|
124 |
+ msg->hash_index=hash( msg->callid->body, get_cseq(msg)->number); |
|
125 |
+ if (!branch_builder( msg->hash_index, 0, md5, 0 /* 0-th branch */, |
|
126 |
+ msg->add_to_branch_s, &msg->add_to_branch_len )) { |
|
127 |
+ LOG(L_ERR, "ERROR: forward_request: branch_builder failed\n"); |
|
128 |
+ goto error1; |
|
129 |
+ } |
|
130 |
+ } |
|
131 |
+ |
|
104 | 132 |
buf = build_req_buf_from_sip_req( msg, &len, send_sock); |
105 | 133 |
if (!buf){ |
106 |
- LOG(L_ERR, "ERROR: forward_reply: building failed\n"); |
|
107 |
- goto error; |
|
134 |
+ LOG(L_ERR, "ERROR: forward_request: building failed\n"); |
|
135 |
+ goto error1; |
|
108 | 136 |
} |
109 | 137 |
/* send it! */ |
110 | 138 |
DBG("Sending:\n%s.\n", buf); |
... | ... |
@@ -116,7 +144,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
116 | 144 |
p->errors++; |
117 | 145 |
p->ok=0; |
118 | 146 |
STATS_TX_DROPS; |
119 |
- goto error; |
|
147 |
+ goto error1; |
|
120 | 148 |
} |
121 | 149 |
/* sent requests stats */ |
122 | 150 |
else STATS_TX_REQUEST( msg->first_line.u.request.method_value ); |
... | ... |
@@ -124,13 +152,26 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p) |
124 | 152 |
free(to); |
125 | 153 |
/* received_buf & line_buf will be freed in receiv_msg by free_lump_list*/ |
126 | 154 |
return 0; |
155 |
+ |
|
156 |
+error1: |
|
157 |
+ free(to); |
|
127 | 158 |
error: |
128 | 159 |
if (buf) pkg_free(buf); |
129 |
- if (to) free(to); |
|
130 | 160 |
return -1; |
131 | 161 |
} |
132 | 162 |
|
133 | 163 |
|
164 |
+int update_sock_struct_from_ip( union sockaddr_union* to, |
|
165 |
+ struct sip_msg *msg ) |
|
166 |
+{ |
|
167 |
+ to->sin.sin_port=(msg->via1->port) |
|
168 |
+ ?htons(msg->via1->port): htons(SIP_PORT); |
|
169 |
+ to->sin.sin_family=msg->src_ip.af; |
|
170 |
+ memcpy(&to->sin.sin_addr, &msg->src_ip.u, msg->src_ip.len); |
|
171 |
+ |
|
172 |
+ return 1; |
|
173 |
+} |
|
174 |
+ |
|
134 | 175 |
int update_sock_struct_from_via( union sockaddr_union* to, |
135 | 176 |
struct via_body* via ) |
136 | 177 |
{ |
... | ... |
@@ -252,9 +293,10 @@ int forward_reply(struct sip_msg* msg) |
252 | 293 |
if (mod->exports->response_f(msg)==0) goto skip; |
253 | 294 |
} |
254 | 295 |
} |
255 |
- |
|
296 |
+ |
|
256 | 297 |
/* we have to forward the reply stateless, so we need second via -bogdan*/ |
257 |
- if ((msg->via2==0) || (msg->via2->error!=PARSE_OK)) |
|
298 |
+ if (parse_headers( msg, HDR_VIA2, 0 )==-1 |
|
299 |
+ || (msg->via2==0) || (msg->via2->error!=PARSE_OK)) |
|
258 | 300 |
{ |
259 | 301 |
/* no second via => error */ |
260 | 302 |
LOG(L_ERR, "ERROR: forward_msg: no 2nd via found in reply\n"); |
... | ... |
@@ -16,6 +16,8 @@ struct socket_info* get_send_socket(union sockaddr_union* su); |
16 | 16 |
int forward_request( struct sip_msg* msg, struct proxy_l* p); |
17 | 17 |
int update_sock_struct_from_via( union sockaddr_union* to, |
18 | 18 |
struct via_body* via ); |
19 |
+int update_sock_struct_from_ip( union sockaddr_union* to, |
|
20 |
+ struct sip_msg *msg ); |
|
19 | 21 |
int forward_reply( struct sip_msg* msg); |
20 | 22 |
|
21 | 23 |
#endif |
... | ... |
@@ -44,8 +44,10 @@ extern int children_no; |
44 | 44 |
extern int dont_fork; |
45 | 45 |
extern int check_via; |
46 | 46 |
extern int received_dns; |
47 |
-extern int loop_checks; |
|
47 |
+extern int syn_branch; |
|
48 | 48 |
extern int process_no; |
49 |
+extern int sip_warning; |
|
50 |
+extern int server_signature; |
|
49 | 51 |
/* |
50 | 52 |
* debug & log_stderr moved to dprint.h*/ |
51 | 53 |
|
... | ... |
@@ -57,4 +59,13 @@ extern unsigned int msg_no; |
57 | 59 |
|
58 | 60 |
extern unsigned int shm_mem_size; |
59 | 61 |
|
62 |
+/* FIFO server config */ |
|
63 |
+char extern *fifo; /* FIFO name */ |
|
64 |
+extern int fifo_mode; |
|
65 |
+ |
|
66 |
+extern int *pids; |
|
67 |
+extern int process_no; |
|
68 |
+ |
|
69 |
+extern int reply_to_via; |
|
70 |
+ |
|
60 | 71 |
#endif |
... | ... |
@@ -36,6 +36,7 @@ |
36 | 36 |
#include "resolve.h" |
37 | 37 |
#include "parser/parse_hname2.h" |
38 | 38 |
#include "parser/digest/digest_parser.h" |
39 |
+#include "fifo_server.h" |
|
39 | 40 |
|
40 | 41 |
|
41 | 42 |
#include "stats.h" |
... | ... |
@@ -93,21 +94,6 @@ static char flags[]= |
93 | 94 |
#ifdef DEBUG_DMALLOC |
94 | 95 |
", DEBUG_DMALLOC" |
95 | 96 |
#endif |
96 |
-#ifdef SILENT_FR |
|
97 |
-", SILENT_FR" |
|
98 |
-#endif |
|
99 |
-#ifdef USE_SYNONIM |
|
100 |
-", USE_SYNONIM" |
|
101 |
-#endif |
|
102 |
-#ifdef NOISY_REPLIES |
|
103 |
-", NOISY_REPLIES" |
|
104 |
-#endif |
|
105 |
-#ifdef VERY_NOISY_REPLIES |
|
106 |
-", VERY_NOISY_REPLIES" |
|
107 |
-#endif |
|
108 |
-#ifdef NEW_HNAME |
|
109 |
-", NEW_HNAME" |
|
110 |
-#endif |
|
111 | 97 |
#ifdef FAST_LOCK |
112 | 98 |
", FAST_LOCK" |
113 | 99 |
#ifdef BUSY_WAIT |
... | ... |
@@ -125,7 +111,6 @@ static char flags[]= |
125 | 111 |
static char help_msg[]= "\ |
126 | 112 |
Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\ |
127 | 113 |
Options:\n\ |
128 |
- -c Perform loop checks and compute branches\n\ |
|
129 | 114 |
-f file Configuration file (default " CFG_FILE ")\n\ |
130 | 115 |
-p port Listen on the specified port (default: 5060)\n\ |
131 | 116 |
applies to the last address in -l and to all \n\ |
... | ... |
@@ -173,8 +158,8 @@ void print_ct_constants() |
173 | 158 |
#endif |
174 | 159 |
*/ |
175 | 160 |
printf("MAX_RECV_BUFFER_SIZE %d, MAX_LISTEN %d," |
176 |
- " MAX_URI_SIZE %d, MAX_PROCESSES %d, BUF_SIZE %d\n", |
|
177 |
- MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE, MAX_PROCESSES, |
|
161 |
+ " MAX_URI_SIZE %d, BUF_SIZE %d\n", |
|
162 |
+ MAX_RECV_BUFFER_SIZE, MAX_LISTEN, MAX_URI_SIZE, |
|
178 | 163 |
BUF_SIZE ); |
179 | 164 |
} |
180 | 165 |
|
... | ... |
@@ -209,14 +194,29 @@ int sig_flag = 0; /* last signal received */ |
209 | 194 |
int debug = 0; |
210 | 195 |
int dont_fork = 0; |
211 | 196 |
int log_stderr = 0; |
212 |
-int check_via = 0; /* check if reply first via host==us */ |
|
213 |
-int loop_checks = 0; /* calculate branches and check for loops/spirals */ |
|
214 |
-int received_dns = 0; /* use dns and/or rdns or to see if we need to |
|
215 |
- add a ;received=x.x.x.x to via: */ |
|
197 |
+/* check if reply first via host==us */ |
|
198 |
+int check_via = 0; |
|
199 |
+/* shall use stateful synonym branches? faster but not reboot-safe */ |
|
200 |
+int syn_branch = 0; |
|
201 |
+/* should replies include extensive warnings? by default yes, |
|
202 |
+ good for trouble-shooting |
|
203 |
+*/ |
|
204 |
+int sip_warning = 1; |
|
205 |
+/* should localy-generated messages include server's signature? |
|
206 |
+ be default yes, good for trouble-shooting |
|
207 |
+*/ |
|
208 |
+int server_signature=1; |
|
209 |
+/* use dns and/or rdns or to see if we need to add |
|
210 |
+ a ;received=x.x.x.x to via: */ |
|
211 |
+int received_dns = 0; |
|
216 | 212 |
char* working_dir = 0; |
217 | 213 |
char* chroot_dir = 0; |
218 | 214 |
int uid = 0; |
219 | 215 |
int gid = 0; |
216 |
+/* a hint to reply modules whether they should send reply |
|
217 |
+ to IP advertised in Via or IP from which a request came |
|
218 |
+*/ |
|
219 |
+int reply_to_via=0; |
|
220 | 220 |
|
221 | 221 |
#if 0 |
222 | 222 |
char* names[MAX_LISTEN]; /* our names */ |
... | ... |
@@ -497,6 +497,12 @@ int main_loop() |
497 | 497 |
LOG(L_ERR, "init_child failed\n"); |
498 | 498 |
goto error; |
499 | 499 |
} |
500 |
+ |
|
501 |
+ /* if configured to do so, start a server for accepting FIFO commands */ |
|
502 |
+ if (open_fifo_server()<0) { |
|
503 |
+ LOG(L_ERR, "opening fifo server failed\n"); |
|
504 |
+ goto error; |
|
505 |
+ } |
|
500 | 506 |
is_main=1; /* hack 42: call init_child with is_main=0 in case |
501 | 507 |
some modules wants to fork a child */ |
502 | 508 |
|
... | ... |
@@ -543,6 +549,11 @@ int main_loop() |
543 | 549 |
/*close(udp_sock)*/; /*if it's closed=>sendto invalid fd errors?*/ |
544 | 550 |
} |
545 | 551 |
} |
552 |
+ /* if configured to do so, start a server for accepting FIFO commands */ |
|
553 |
+ if (open_fifo_server()<0) { |
|
554 |
+ LOG(L_ERR, "opening fifo server failed\n"); |
|
555 |
+ goto error; |
|
556 |
+ } |
|
546 | 557 |
/*this is the main process*/ |
547 | 558 |
pids[process_no]=getpid(); |
548 | 559 |
process_bit = 0; |
... | ... |
@@ -590,6 +601,7 @@ int main_loop() |
590 | 601 |
static void sig_usr(int signo) |
591 | 602 |
{ |
592 | 603 |
|
604 |
+ |
|
593 | 605 |
if (is_main){ |
594 |