unsigned short flags;
int_str name, value;
str* dst_host;
+ int orig_p2t;
/* reset the value of error to E_UNSPEC so avoid unknowledgable
functions to return with error (status<0) and not setting it
case PREFIX_T:
case STRIP_T:
case STRIP_TAIL_T:
+ case SET_USERPHONE_T:
user=0;
if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
if (a->val[0].type!=NUMBER_ST) {
LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
a->val[0].type);
+ ret=E_BUG;
break;
}
- } else if (a->val[0].type!=STRING_ST){
- LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
+ } else if (a->type!=SET_USERPHONE_T) {
+ if (a->val[0].type!=STRING_ST) {
+ LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
a->val[0].type);
- ret=E_BUG;
- break;
+ ret=E_BUG;
+ break;
+ }
}
if (a->type==SET_URI_T){
if (msg->new_uri.s) {
ret=1;
break;
}
- if (msg->parsed_uri_ok==0) {
+ if ((msg->parsed_uri_ok==0) || ((uri.flags & URI_SIP_USER_PHONE)!=0)) {
if (msg->new_uri.s) {
tmp=msg->new_uri.s;
len=msg->new_uri.len;
tmp=msg->first_line.u.request.uri.s;
len=msg->first_line.u.request.uri.len;
}
+ /* don't convert sip:user=phone to tel, otherwise we loose parameters */
+ orig_p2t=phone2tel;
+ phone2tel=0;
+ msg->parsed_uri_ok=0;
if (parse_uri(tmp, len, &uri)<0){
+ phone2tel=orig_p2t;
LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
" packet\n", tmp);
ret=E_UNSPEC;
break;
}
+ phone2tel=orig_p2t;
} else {
uri=msg->parsed_uri;
}
+ /* skip SET_USERPHONE_T action if the URI is already
+ * a tel: or tels: URI, or contains the user=phone param */
+ if ((a->type==SET_USERPHONE_T)
+ && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T)
+ || ((uri.user_param_val.len==5) && (memcmp(uri.user_param_val.s, "phone", 5)==0)))
+ ) {
+ ret=1;
+ break;
+ }
+ /* SET_PORT_T does not work with tel: URIs */
+ if ((a->type==SET_PORT_T)
+ && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
+ && ((uri.flags & URI_SIP_USER_PHONE)==0)
+ ) {
+ LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
+ ret=E_UNSPEC;
+ break;
+ }
+
new_uri=pkg_malloc(MAX_URI_SIZE);
if (new_uri==0){
LOG(L_ERR, "ERROR: do_action: memory allocation "
end=new_uri+MAX_URI_SIZE;
crt=new_uri;
/* begin copying */
- len=strlen("sip:"); if(crt+len>end) goto error_uri;
- memcpy(crt,"sip:",len);crt+=len;
+ /* Preserve the URI scheme unless the host part needs
+ * to be rewritten, and the shceme is tel: or tels: */
+ switch (uri.type) {
+ case SIP_URI_T:
+ len=s_sip.len;
+ tmp=s_sip.s;
+ break;
+
+ case SIPS_URI_T:
+ len=s_sips.len;
+ tmp=s_sips.s;
+ break;
+
+ case TEL_URI_T:
+ if ((uri.flags & URI_SIP_USER_PHONE)
+ || (a->type==SET_HOST_T)
+ || (a->type==SET_HOSTPORT_T)
+ || (a->type==SET_HOSTPORTTRANS_T)
+ ) {
+ len=s_sip.len;
+ tmp=s_sip.s;
+ break;
+ }
+ len=s_tel.len;
+ tmp=s_tel.s;
+ break;
+
+ case TELS_URI_T:
+ if ((uri.flags & URI_SIP_USER_PHONE)
+ || (a->type==SET_HOST_T)
+ || (a->type==SET_HOSTPORT_T)
+ || (a->type==SET_HOSTPORTTRANS_T)
+ ) {
+ len=s_sips.len;
+ tmp=s_sips.s;
+ break;
+ }
+ len=s_tels.len;
+ tmp=s_tels.s;
+ break;
+
+ default:
+ LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
+ "reverted to sip:\n",
+ uri.type);
+ len=s_sip.len;
+ tmp=s_sip.s;
+ }
+ if(crt+len+1 /* colon */ >end) goto error_uri;
+ memcpy(crt,tmp,len);crt+=len;
+ *crt=':'; crt++;
/* user */
memcpy(crt,tmp,len);crt+=len;
}
/* host */
- if (user || tmp){ /* add @ */
- if(crt+1>end) goto error_uri;
- *crt='@'; crt++;
- }
if ((a->type==SET_HOST_T)
|| (a->type==SET_HOSTPORT_T)
- || (a->type==SET_HOSTPORTTRANS_T)) {
+ || (a->type==SET_HOSTPORTTRANS_T)
+ ) {
tmp=a->val[0].u.string;
if (tmp) len = strlen(tmp);
else len=0;
- } else {
+ } else if ((uri.type==SIP_URI_T)
+ || (uri.type==SIPS_URI_T)
+ || (uri.flags & URI_SIP_USER_PHONE)
+ ) {
tmp=uri.host.s;
- len = uri.host.len;
+ len=uri.host.len;
+ } else {
+ tmp=0;
}
if (tmp){
+ if (user) { /* add @ */
+ if(crt+1>end) goto error_uri;
+ *crt='@'; crt++;
+ }
if(crt+len>end) goto error_uri;
memcpy(crt,tmp,len);crt+=len;
}
memcpy(crt,tmp,len);crt+=len;
}
}
+ /* Add the user=phone param if a tel: or tels:
+ * URI was converted to sip: or sips:.
+ * (host part of a tel/tels URI was set.)
+ * Or in case of sip: URI and SET_USERPHONE_T action */
+ if (((((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
+ && ((uri.flags & URI_SIP_USER_PHONE)==0))
+ && ((a->type==SET_HOST_T)
+ || (a->type==SET_HOSTPORT_T)
+ || (a->type==SET_HOSTPORTTRANS_T)))
+ || (a->type==SET_USERPHONE_T)
+ ) {
+ tmp=";user=phone";
+ len=strlen(tmp);
+ if(crt+len>end) goto error_uri;
+ memcpy(crt,tmp,len);crt+=len;
+ }
/* headers */
tmp=uri.headers.s;
if (tmp){
* 2007-11-28 added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
* LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
* 2008-01-24 added CFG_DESCRIPTION used by cfg_var (Miklos)
+ * 2009-03-10 added SET_USERPHONE action (Miklos)
*/
PREFIX "prefix"
STRIP "strip"
STRIP_TAIL "strip_tail"
+SET_USERPHONE "userphone"
APPEND_BRANCH "append_branch"
IF "if"
ELSE "else"
<INITIAL>{STRIP_TAIL} { count(); yylval.strval=yytext; return STRIP_TAIL; }
<INITIAL>{APPEND_BRANCH} { count(); yylval.strval=yytext;
return APPEND_BRANCH; }
+<INITIAL>{SET_USERPHONE} { count(); yylval.strval=yytext;
+ return SET_USERPHONE; }
<INITIAL>{FORCE_RPORT} { count(); yylval.strval=yytext; return FORCE_RPORT; }
<INITIAL>{FORCE_TCP_ALIAS} { count(); yylval.strval=yytext;
return FORCE_TCP_ALIAS; }
* 2007-11-28 added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
* LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
* 2008-01-24 added cfg_var definition (Miklos)
+ * 2009-03-10 added SET_USERPHONE action (Miklos)
*/
%{
%token PREFIX
%token STRIP
%token STRIP_TAIL
+%token SET_USERPHONE
%token APPEND_BRANCH
%token SET_USER
%token SET_USERPASS
| STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, 1, NUMBER_ST, (void*) $3); }
| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
+ | SET_USERPHONE LPAREN RPAREN { $$=mk_action(SET_USERPHONE_T, 0); }
+ | SET_USERPHONE error { $$=0; yyerror("missing '(' or ')' ?"); }
| APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN {
qvalue_t q;
if (str2q(&q, $5, strlen($5)) < 0) {