Using DblQuote char in SIP Headers Causes Mayhem

Attempting a workaround for a different issue I sought to effect this following, simple task:
- have a ‘custom’ SIP header, of my own making, added to my INVITE when I placed a call

The header (keyname) I wanted to add would be named:
and the content (value) which I wanted it to contain would be:
“skunk” sip:[email protected]

So I’ll just invoke:
func-set-sipheader,s,1(P-Asserted-Identity,“skunk” sip:[email protected])

Oh no.

Out the wire I actaully get this as the content (value):;info=“skunk” sip:[email protected]
which is to say that the following muckykuck gets prepended to what I wanted the header to contain:;info=


I tried working around this by escaping each dblquote char with a backslash, or using \x22 or \042 in lieu, and none paid off.

The same spurious chars get prepended if one attempts to doublequote the keyname.

Most perniciously: when one backslash-escapes a set of doublequotes in the value side of the header then other, behaving custom SIP headers that one has added just start /not/ showing up. Havoc ensues.

So my question would then be: how does one include the doublequote char (and only the doublequote char), at will, in the keyname and value side of a SIP header?

Failing my question bearing any fruit I’d then suggest this is a bug?

Thx for any info!

Before exploring this further, what do you need in P-Asserted-Identity that the built-in features won’t do?

Whilst re-iterating Stewart’s question about why you are not using Asterisk’s built in P-Asserted-Identity processing, could I also ask why do you need the quotes in the first place? Even allowing that you didn’t mark it up properly for the forum, the following would have been syntactically valid and would be treated the same as one with the quotes as a well as the angle brackets, by all normal implementations:

P-Asserted-Identity: skunk <sip:[email protected]>

I see a lot of people trying to hand craft PAI when they are just reproducing what Asterisk will do when properly configured.

PS you haven’t said which SIP channel driver you are using.

1 Like

[quote=“Stewart1, post:2, topic:77507, full:true”]what do you need in P-Asserted-Identity that the built-in features won’t do?[/quote]I am able to send (manually constructed) SIPheader “Privacy=id”. However if I activate the GUI feature to sendPAI then it stops sending header “Privacy=id” (as I posted here: [Bug?] SIPheader WARS: P-Asserted-ID 'kills' Privacy:id ?!?!?! ).

So In response I’m trying to send my own PAI header, hoping that if I do it myself then it won’t ‘kill’ my “Privacy=id” header.


This is why you shouldn’t start multiple threads on the same problem!

Could a moderator possibly merge them.

I’m using pjSIP.

I wanted the doublequote chars to identically replicate what fPBX puts out in its own PAI header.

(Thx for being cognizant of the markup mangling in my post!)

I’m attempting to do what */fPBX does itself, normally (i.e. send PAI) because of this bug (?) I’ve discovered: [Bug?] SIPheader WARS: P-Asserted-ID 'kills' Privacy:id ?!?!?!

It is about the same overall goal and it is clearly necessary to read it in order to understand why you are doing what you are doing in the current thread.

Unfortunately, I never read chan_pjsip in enough depth to be able to easily find my way around it, but it seems very weird that it, or the FreePBX function is adding an HTTP URL. The first thing I’d want to look at (after fully investigating the way that Privacy is generated) would be a verbose log of the add header function in FreePBX, to eliminate that as a source of the mangling.

I tested this with the PJSIP_HEADER function by adding this simple dialplan to extensions_custom.conf:

exten => addheader,1,Set(PJSIP_HEADER(add,x-test-header)="tommy tutone" <8008675309>)

exten => 10000,1,Dial(PJSIP/[email protected],,b(addheaderhandler^addheader^1))
same => n,hangup()

Result from dialing 10000:

INVITE sip:[email protected] SIP/2.0
Via: ...
x-test-header: "tommy tutone" <8008675309>

So, strictly speaking, quotes are not a problem. Maybe the custom function you are using doesn’t like them.

1 Like

I suspect these threads are really about not having caller ID marked as unverified, as a result of being slow to support STIR/SHAKEN well:

I can’t find anything about it on their searchable web site, but maybe Policy: Id causes them to present a network provider ID. However, I can’t think of any good reason for sending them PAI in the first place, if that is what is wanted. Maybe they are going to provide verified status if the user provided ID matches the network provided one, in which case that is probably the best approach, rather than sending one they must mark as unverified, then saying don’t use it.

I do half wonder if the OP is expecting the Display Name to get through, but privacy: id appears to me to be intended to affect the whole ID, not just the machine processable part.

There seem to be a lot of users here, so either there is going to be a rush of topics, if the change just went in and is causing them problems, or most people have an acceptable solution already.

FWIW I’m adding the headers via extensions_custom.conf containing:
    exten => s,n,GoSubIf($[ “${CALLERID(name)}” = “skunk” ]?func-set-sipheader,s,1(“Test2–Q-NQ”,sample2))

If you look through the Asterisk log (/var/log/asterisk/full) you will probably be able to spot what’s going wrong.

Here are the subs you are using:

include => func-set-sipheader-custom
exten => s,1,Noop(Sip Add Header function called. Adding ${ARG1} = ${ARG2})
exten => s,n,Set(HASH(__SIPHEADERS,${ARG1})=${ARG2})
exten => s,n,Return()

;--== end of [func-set-sipheader] ==--;

include => func-apply-sipheaders-custom
exten => s,1,Noop(Applying SIP Headers to channel ${CHANNEL})
exten => s,n,Set(TECH=${CUT(CHANNEL,/,1)})
exten => s,n,While($["${SET(sipkey=${SHIFT(SIPHEADERKEYS)})}" != ""])
exten => s,n,Set(sipheader=${HASH(SIPHEADERS,${sipkey})})
exten => s,n,ExecIf($["${sipheader}" = "unset" & "${TECH}" = "PJSIP"]?Set(PJSIP_HEADER(remove,${sipkey})=))
exten => s,n,ExecIf($["${sipheader}" != "unset" & "${sipkey}" = "Alert-Info" & ${REGEX("^<[^>]*>" ${sipheader})} != 1 & ${REGEX("\;info=" ${sipheader})} != 1]?Set(sipheader=<>\;info=${sipheader}))
exten => s,n,ExecIf($["${sipheader}" != "unset" & "${sipkey}" = "Alert-Info" & ${REGEX("^<[^>]*>" ${sipheader})} != 1]?Set(sipheader=<>${sipheader}))
exten => s,n,ExecIf($["${TECH}" = "PJSIP" & "${sipheader}" != "unset"]?Set(PJSIP_HEADER(add,${sipkey})=${sipheader}))
exten => s,n,EndWhile
exten => s,n,Return()

Actually, they’re about precisely what they say they are about.

As it happens my interest in these various minutiae of how things work is due to my interest in mimicing what *67 does on ILEC wireline, but one does not need to know that to understand my inquiry here, say about dblquotechars.

Oops there, it’s actually /this/ header:


Can we please avoid veering offtopic here.

I’m in Canada, we have no S/S here, so I don’t have one iota of concern for it, at this time.

STIR/SHAKEN is a US and Canada thing. Canada just had longer to make it happened.

@Blaze, yeah, I get that it’s on the horizon and appreciate the heads up, but it’s not part of my /current/ woes (thankfully).

Heh, well, it’s pretty obvious from looking at the code - the content gets dblquoted as part of comparison operations, so mayhem is inevitable if the content itself contains the same characters.

So then is it a shortcoming (bug) of the code to be unable to handle dblquote chars - or a ‘feature/limitation’ sorta thing?

IMO it looks like such dblquote chars are part of the reasonably-expectatable set of what one shall encounter…

Why not just use the Asterisk function PJSIP_HEADER instead of the FreePBX subroutine?

@billsimon - to answer your question, cuz I didn’t know of it (function PJSIP_HEADER).

Though having tried, it seems to be unworking; to wit, this:

    exten => s,n,GoSubIf($[ "${CALLERID(name)}" = "######_2PBXhideCID" ]?func-set-sipheader,s,1(1_BEFORE,BEFORE))
    exten => s,n,ExecIf($[ "${CALLERID(name)}" = "######_2PBXhideCID" ]?Set(PJSIP_HEADER(add,X-MyHeader1)=myvalue1))
    exten => s,n,GoSubIf($[ "${CALLERID(name)}" = "######_2PBXhideCID" ]?func-set-sipheader,s,1(2_AFTER,AFTER))

gives me the BEFORE and AFTER headers, but X-MyHeader1 is completely absent.

I’ll give it another go if anyone’s got a correction for me.

I don’t know where in the dialplan you have those lines but if you want the PJSIP header applied to the outbound call leg it has to be done like I did with the b-leg parameter on the Dial command. Otherwise you are setting a SIP header on the a-leg which probably isn’t what you want.

1 Like

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.