usnistgov / jsip

JSIP: Java SIP specification Reference Implementation (moved from java.net)
Other
287 stars 130 forks source link

TCP transport is not working after version 1.2.324 #57

Open theeasiestway opened 4 years ago

theeasiestway commented 4 years ago

Hello, i noticed that a TCP transport doesn't work after version 1.2.324. I tried to register my sip account on different sip servers but result the same: I send registration request to sip server, at this point everething is ok the sip server receives my request, after that sip server send me 401 Unauthorized response and when i received this response the registration process stucks and then nothing happens. Sometimes (but very rarely) the registration process successfully complete but in this case after the registration i can't receive any calls or update or delete my registration it looks like sip stack stucks and due to this it can't handle any requests. I also want to note that in the same cases everething works fine if i use an UDP transport.

vladimirralev commented 4 years ago

Do you use NIO or blocking socket? Ideally please send debug logs and pcaps to take a look at this.

theeasiestway commented 4 years ago

Do you use NIO or blocking socket?

I don't know, but i configure the stack as follows:

properties.setProperty("android.javax.sip.STACK_NAME", "My_Sip_Stack") properties.setProperty("android.gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "android.gov.nist.javax.sip.stack.NioMessageProcessorFactory") properties.setProperty("android.gov.nist.javax.sip.MAX_TX_LIFETIME_NON_INVITE", 7) sipStack = sipFactory.createSipStack(properties)

Today i checked the latest version (1.3.0-91) from maven repository, i tried to registrate my sip account and make a wireshark dump during it, but with no success - wireshark doesn't show anything and i can show you only my register request:

REGISTER sip:sip.antisip.com:5060 SIP/2.0
Call-ID: 64cc8a41ac01ef22f8980c5d3c06ba98@192.168.28.84
CSeq: 1004 REGISTER
From: "Debug Display Name 111c" <sip:111c@sip.antisip.com>;tag=a7d398eb
To: <sip:111c@sip.antisip.com>
Via: SIP/2.0/TCP 192.168.28.84:24970;rport;branch=z9hG4bK-313934-e10cbdf2155044894461c18eca78bac7
Max-Forwards: 70
User-Agent: SeeS 1.0.0
Contact: <sip:111c@192.168.28.84:24970>
Expires: 120
Content-Length: 0

After that i just get a timeout error in my SipListener's processTimeout method.

vladimirralev commented 4 years ago

You are using NIO. Just to rule out some things can you remove this line?

properties.setProperty("android.gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "android.gov.nist.javax.sip.stack.NioMessageProcessorFactory")

That will disable NIO and will use blocking io stack. After that I may need some debug logs but just want to see if there is something with the IO layer.

theeasiestway commented 4 years ago

Just to rule out some things can you remove this line?

properties.setProperty("android.gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", "android.gov.nist.javax.sip.stack.NioMessageProcessorFactory")

I tried it and everything works fine at least the registration and unregistration. I captured logs and wireshark dumps with and without enabled NIO, i attached them to this message. jainsip_logs.zip

vladimirralev commented 4 years ago

Hmm, I don't get it. The attached logs show that the transport IO works fine in both cases, it's just that the remote party reject the auth in one of the cases. Have you ruled out some kind of credentials typo or remote party auth block?

theeasiestway commented 4 years ago

I couldn't make a typo, because the credentials stored in my app's memory and i just click registrate or remove registration button without change the credentials between the tests with and without NIO. As for auth block by remote party i can't configure the sip server because i'm not it's owner and i think that the server probably configured correctly because this error doesn't reproduce on version 1.2.324. The server is free and doesn't require even an e-mail confirmation so if you need you can registrate two accounts on that server by this link or i can give you my accounts.

vladimirralev commented 4 years ago

I'd rather check the authentication math. Can you share the password for user 111c used in the NIO test?

theeasiestway commented 4 years ago

Sure the password is the same as the login: "111c"

vladimirralev commented 4 years ago

Hmmm, can you please confirm that "111c" was the password at the time when the pcaps were captured? If yes what kind of authentication math are you using to authenticate in this case, is it the qop=auth?

from md5 import md5

login = '111c'
uri = 'sip:sip.antisip.com:5060;maddr=sip.antisip.com'
nonce = 'XlSx015UsKcOXptVoTcqSbiO6ojtBjj4E2rQFuc0DognAtS6pSFYYA=='
realm = 'sip.antisip.com'
password = '111c'
nounceCount = '00000001'
cnounce='xyz'
qop='quth'

str1 = md5("{}:{}:{}".format(login,realm,password)).hexdigest()
str2 = md5("REGISTER:{}".format(uri)).hexdigest()
str3 = md5("{}:{}:{}".format(str1,nonce,str2)).hexdigest()
str4 = md5("{}:{}:{}:{}:{}:{}".format(str1,nonce,nounceCount,cnounce,qop,str2)).hexdigest()
print str3
print str4

this gives

45c7ec25e98994402a8386ae0722b9ce
553937fccc8225b86169da1aaeca53d6

neither of which matches "89142e9cba1f7b2c0c54ddee5de47dc0"

theeasiestway commented 4 years ago

can you please confirm that "111c" was the password at the time when the pcaps were captured?

Yes the password was "111c".

If yes what kind of authentication math are you using to authenticate in this case, is it the qop=auth?

I don't know those details, but for authorization i just use my class "RegistrationHelper" that implements "android.gov.nist.javax.sip.clientauthutils.AccountManager" interface and i use it as follows:

val stack = ControllerSipStacks.getStack(sipAccount!!)
val clientTransaction = responseEvent.clientTransaction
val authenticationHelper = (stack.sipStack as SipStackExt).getAuthenticationHelper(
        RegistrationHelper(
        "111с",
        "sip.antisip.com",
        "111c"
        ), SipStackCore.headerFactory
)
val authClientTransaction = authenticationHelper.handleChallenge(responseEvent.response, clientTransaction, stack.sipProvider, 5)
authClientTransaction.sendRequest()