11

I have a windows desktop application, made by my mobile network provider, that does all kind of things with SIP: call, send message, etc. Screenshot of how does this app successfully send MESSAGE (the last 4 lines): Wireshark

MESSAGE request, from desktop application, is sent as (4th line from behind) :

MESSAGE sip:FROM@DOMAIN SIP/2.0
Via: SIP/2.0/UDP LOCALIP:2112;branch=z9hG4bK-d8754z-905183245f478c76-1---d8754z-;rport
Max-Forwards: 70
To: "TO"<sip:TO@DOMAIN>
From: "FROM"<sip:USERNAME@DOMAIN>;tag=63088d09
Call-ID: NGVhMDJhYzQwNmExOTQyNThmNjc5OGNmOTViNDUyYWM.
CSeq: 2 MESSAGE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: text/plain
Content-Length: 4

test

and successfull response for that is:

SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/UDP LOCALIP:2112;received=EXTERNALIP;branch=z9hG4bK-d8754z-905183245f478c76-1---d8754z-;rport=2112
To: "TO"<sip:TO@DOMAIN>;tag=c005f0e30133ec730add76fc91f4bea
From: "FROM"<sip:USERNAME@DOMAIN>;tag=63088d09
Call-ID: NGVhMDJhYzQwNmExOTQyNThmNjc5OGNmOTViNDUyYWM.
CSeq: 2 MESSAGE
Content-Length: 0
Proxy-Authenticate: Digest nonce="3F178051B97E1F52000123000A3C53D4B",realm="DOMAIN",algorithm=MD5,qop="auth"

Then I try to send identical (and n-variations) request from PHP, but I always receive SIP/2.0 403 Forbidden instead of SIP/2.0 407 Proxy Authentication Required:

SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP LOCALIP;received=EXTERNALIP
To: "TO"<sip:TO@DOMAIN>;tag=aprqngfrt-f7ccjj0000020
From: "FROM"<sip:USERNAME@DOMAIN>;tag=8f7be81d
Call-ID: 526576901edcc@localhost
CSeq: 1 MESSAGE
Reason: Q.850;cause=55;text="Call Terminated"
Content-Length: 0

The funny part is, that if I send REGISTER request it works, and I successfully receive SIP/2.0 401 Unauthorized header with WWW-Authenticate. I recalculate authorization, and resend it. Then I receive SIP/2.0 200 OK. Which is how it should work with MESSAGE.

What could be wrong? What did I miss? Does MESSAGE request need some other request before that (I have already tried REGISTER before)?
I have read RFC 3428 up and down, tried all the examples possible, but without success.

Community
  • 1
  • 1
Glavić
  • 42,781
  • 13
  • 77
  • 107
  • I'm no `SIP` expert and it seems you know what you are doing. All I can say is that if you believe you are doing exactly like the other software (which works) without any lock, I would say go for the things you might be doing differently. Perhaps control characters mismatch could be a good start, like `\n` vs `\n\r`. – Mehran Dec 06 '13 at 14:14
  • @Mehran: I don't think different types of "new-lines" will make any difference, since `REGISTER` method is working. If I, for example, remove `CSeq` header from request, SIP server returns `SIP/2.0 400 Missing CSeq Header`... That tells me, that communication is OK. I think that `MESSAGE` method is sent correct, it must be something else ;( – Glavić Dec 06 '13 at 16:32

2 Answers2

6

If you look into received 403 response, you'll notice a Reason header. The Q.850 string at the beginning indicates that this would be a cause code defined by ITU-T Recomendation.

Specifically, provided cause code 55 is related to ISDN and literary means "Incoming calls barred within Closed User Group" (you can check it in RFC 3398) and, usually, means that, within a group of members, call reception is restricted.

On the other hand, cause 55 also denotes a problem within the request, specially in relation to a user (sender or receiver). Following diagram shows a normal MESSAGE exchange between SIP users:

      A             Server             B
      |    REGISTER    |               |
      |--------------->|               |
      |     200 OK     |               |
      |<---------------|               |
      |                |    REGISTER   |
      |                |<--------------|          
      |                |     200 OK    |
      |                |-------------->|
      |    MESSAGE     |               |
      |--------------->|    MESSAGE    |
      |                |-------------->|
      |                |     200 OK    |
      |                |<--------------|
      |     200 OK     |               |
      |<---------------|               |

Actually, been strict, REGISTER from user A is not needed but most systems (like IMS) uses it as an authentication mechanism. Then, in REGISTER request, special headers are:

Contact: <sip:USER_NAME@LOCAL_IP:LOCAL_PORT>
Expires: REGISTRATION_DURATION

Keep in mind that, 200 OK answers to a REGISTER, can contain an Expires: header or an expires parameter inside Contact: header that indicates accepted expiration time. For example:

SIP/2.0 200 OK
...
Contact: <sip:USER_NAME@LOCAL_IP:LOCAL_PORT>; expires=60 
...

In this situation, you should re-REGISTER before this expiration time (60 seconds in the example).

Keeping in mind that you're trying to send an SMS to a mobile phone, reception point is directly managed by your network provider's MGCF, so this leaves sender's registration or MESSAGE request.

About your original MESSAGE proposal, request URI (message's first line), should be:

 MESSAGE sip:TO@DOMAIN SIP/2.0

Because it refers to MESSAGE reception entity.

Hope this helps.

jcm
  • 2,568
  • 14
  • 18
  • @Glavić You can get some information about relation between Q.850 codes and SIP in [RFC 3398](https://www.ietf.org/rfc/rfc3398.txt). About MESSAGE request URI, you should not provide information about your user (neither my_phone_num or username) but about _destination_, this is `TO` value. Most proxy servers does only check this request URI for message forwarding and, actually, it would match your problem, you're trying to send a MESSAGE to yourself. – jcm Dec 08 '13 at 14:02
  • @Glavić If you're trying to send a SMS, have you tried Tel URI format: tel:+ instead of sip:TO@DOMAIN? – jcm Dec 08 '13 at 14:17
  • @Glavić Cause code 55, initially, means some kind of restriction over this user in provided working group (management unit), but also can refer a request <--> user incompatibility. From your previous messages I assume you already registered the caller and callee users before sending the MESSAGE, am I wrong? – jcm Dec 08 '13 at 14:50
  • @Glavić Yes, in order to send sip MESSAGE from user A to B, you will need to register both users and, once both are registered, send the MESSAGE request. Are you running your php code on your laptop? If so, is it possible that you provide a network capture that I check? – jcm Dec 08 '13 at 15:28
  • @Glavić This picture only shows message exchange but not details. In SIP the scenario is really important and some details can change it a lot. On the other hand, with windows application and CSipSimple, are you also sending a message to yourself? are you using tel or sip schemes? Are you enabling MESSAGE reception in your REGISTER?. As you can see, a lot of questions that can be directly answered with a cap file. – jcm Dec 09 '13 at 11:10
  • @Glavić I know I'm asking too much but, can you, please provide same info from your desktop application or CSipSimple? At first glance, I can't see any possible issue in this scenario only that, initially, if you use phone_number you should be using a tel scheme (tel:phone_number) but this depend on your network provider. – jcm Dec 09 '13 at 12:30
  • 1
    @Glavić I have not checked new details but, I noticed that, in your REGISTER message you lacks Contact header. This is very important because, although this is a location mechanism, some systems uses it as an authentication process, enabling an end point. Your Contact header should look like: `Contact: ` – jcm Dec 09 '13 at 13:43
  • @Glavić I'm glad it worked! SIP systems are sometimes a bit tricky ;-). Answer updated, please, note extra comments I added regarding `expires` parameter in 200 OK to REGISTER, is important to keep this in mind. Hope this also helps other people! – jcm Dec 09 '13 at 15:22
  • Nice answer! In my example, expire is returned in `Contact:` header like `...;expires=1114`; good to know info, but in my example, sending SMS will be something like 2 second job. SIP is new to me, but like you said, it can be a little tricky ;) THANKS again! – Glavić Dec 09 '13 at 15:30
2

As I've told you in comments, I'm no SIP expert but a friend of mine is. I've asked him about your case and this is what he told me:

SIP protocol is a dialogue protocol meaning that each communication is a dialogue with a unique dialogue ID (something like session ID in HTTP). The difference between SIP and HTTP is that session ID is used among different TPC/IP connections (HTTP requests) while dialogue ID is used within the same TPC/IP connection but among different messages.

It seems to me that what you are trying to do here is somewhat like session hijacking in HTTP. While it is possible to hijack a session ID in HTTP and sent it from another client, the same is not for SIP. According to my friend SIP servers have an internal memory of which dialogue ID belongs to which connection and you can not slip your messages into someone else's dialogue just by knowing their dialogue ID.

Your question does not say if this is what actually you are trying to do, but in case it is, then I must say you can't. The fact that you can send the REGISTER command shows that your communication to SIP server is made. All you need to do is to initiate your own dialogue and take it from there.

Mehran
  • 15,593
  • 27
  • 122
  • 221
  • If you are trying to implement a SIP stack in PHP why you are not using available libraries? Here's one: https://code.google.com/p/php-sip/ . I'm sure you can find plenty of such projects on the Internet. – Mehran Dec 07 '13 at 10:47
  • Unfortunately no. But if you have already tested several libraries communicating with a SIP server with no success, then I must say you need to make sure that your server is not acting weird. I mean not all the libraries out there could be malfunctioning! – Mehran Dec 09 '13 at 11:06