kirm / sip.js

Session Initiation Protocol for node.js
MIT License
431 stars 171 forks source link

Loose-routing parameter lost on send #154

Closed FabioDominio closed 2 years ago

FabioDominio commented 2 years ago

When I add the "route" header to a message, the latter is correctly formatted but the actually sent one is different because the message uri is switched with the routing uri so the SIP server cannot deliver it to the recipient.

While I was debugging the SIP library code I noticed that this was due to the lack of the "lr" parameter in the routing uri that forced a rotation of the uris because of the check in line 1396 of "sip.js".

However, even after juxtaposing ";lr" to the routing uri, nothing changes because the lr parameter is correctly detected and retained in the next hop until line 1392, but is then lost right after as the next hop is entirely replaced by the routing header object parsed in the previous lines.

I was able to overcome the issue by patching line 1392 of sip.js with:

hop = parseUri(m.headers.route[0].uri);
hop.params = m.headers.route[0].params;

to restore the lost parameters, but I am not sure it is the right way to fix the issue.

Here it is an example of message I was sending and that raised the issue. I omitted the sensible information for privacy reasons.

const message = {
    method: 'MESSAGE',
    uri: 'sip:johndoe@***',
    headers: {
        route: 'sip:***:1234;lr',
        to: {
            uri: 'sip:johndoe@***'
        },
        from:{
            uri: 'sip:service@***',
            params: {
                tag: Number(Math.floor(Math.random() * 1e5))
            },
        },
        'call-id': Number(Math.floor(Math.random() * 1e5)),
        cseq: {
            method: 'MESSAGE',
            seq: Math.floor(Math.random() * 1e5)
        },
        'content-type': 'text/plain',
    },
    content: 'TEST',
};

Mind how the SIP proxy domain is not the same domain of the registered user (johndoe), and the the "service" user which is, instead, not registered but is allowed to send messages directly to the proxy to be routed by the end users.

I had to specify the routing header because by design the users' domains are resolved only within our network, they are not addressed by a public DNS.

By patching the code as indicated I am able to send messages to the end users.

Thanks.

kirm commented 2 years ago

Ok, the problem here is that while parsing route header route: 'sip:***:1234;lr' lr is parsed as a route header parameter, not an uri param. As far as i remember it is correct behaviour (according to header grammar in the spec). You can fix it but explicitly marking lr as an uri parameter in your code - ie pass route: '<sip:***:1234;lr>' to sip.js.

FabioDominio commented 2 years ago

Hello @kirm,

I tried what you suggested and it was right: if I enclose the route in angular brackets and remove my patch, the "lost" parameter is no longer lost and the message and routing uris are no longer switched.

The code is good as it is and does not need my patch.

Thanks again for the clarification.

Fabio