Export to GitHub

csipsimple - issue #390

OpenVPN support


Posted on Nov 18, 2010 by Happy Bear

What steps will reproduce the problem? 1.Have an asterisk server in a VPN 2.Connect with phone to that VPN 3.Tell csipsimple to connect to the server in the VPN

What is the expected output? What do you see instead? Cannot register

What version of the product are you using? On what operating system? 0.00-15 on Cyanogenmod 6.0 (Froyo)

Please provide any additional information below. routing problem?

Comment #1

Posted on Nov 18, 2010 by Quick Hippo

Yes you're right I nothing is done for VPN for now. I'll do that soon but have to root one of my phones to be able to see how things goes with OpenVPN.

Comment #2

Posted on Nov 18, 2010 by Massive Cat

on both my adp1 and my n1 using openvpn on Cyanogenmod 6.0 I had no problem registering csipsimple to asterisk set to listen on the internal openvpn ip/bridge. Often quality was choppy but I was able to register.

Do you have something like a openvpn connecting on tcp and asterisk listening on udp?

Comment #3

Posted on Nov 18, 2010 by Massive Cat

also, I should add chopyness was probably due to my lack of openvpn/asterisk tuning skill. Its been crystal clear since Ive dropped openvpn and utilized encryption in the tls/srtp build.

Comment #4

Posted on Nov 19, 2010 by Happy Bear

I have asterisk listening on OpenVPN internal ip. Both, asterisk and OpenVPN are listening on UDP sockets and I keep having timeout on registering. With SipDroid I have no troubles registering (but it does not support 2G).

Thanks for the reply.

Comment #5

Posted on Nov 21, 2010 by Happy Bear

Well, anyway, if I can help with some test, just ask me to do it. Right now I think that csipsimple is not sending packages through the VPN. Any clues ?

Comment #6

Posted on Jan 23, 2011 by Quick Hippo

Issue 588 has been merged into this issue.

Comment #7

Posted on Jan 30, 2011 by Happy Lion

Comment deleted

Comment #8

Posted on Jan 30, 2011 by Happy Lion

It seems that csipsimple suffers from the same bug(/feature) as SipDroid. See: http://code.google.com/p/sipdroid/issues/detail?id=368#c10).

I can confirm by looking at the debug log from asterisk that csipsimple sends the ip-address from the wrong interface when using VPN.


<--- SIP read from UDP:172.16.0.6:5060 ---> REGISTER sip:172.16.0.1 SIP/2.0 Via: SIP/2.0/UDP MY_3G_IP_ADDRESS:5060;rport;branch=z9hG4bKPjqudlk.qa7d22EpWk3Kx.7A6C.3GkFuBm Max-Forwards: 70 From: "MY ID" ;tag=lZK4v7vKXhr0v6hUFv7tuKhxlybJ9vtj To: "MY CALLER ID" Call-ID: oqMbT7BmUuT6OkcOARr0zegF7OQrvnIC CSeq: 41338 REGISTER User-Agent: CSipSimple Contact: "MY ID" Expires: 300 Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS Content-Length: 0

<-------------> --- (12 headers 0 lines) --- Sending to MY_3G_IP_ADDRESS : 5060 (no NAT)


btw. The patch for sipdroid looks relatively simple. Isn't this an option to include here as well? A more elegant way could be that upon connecting, we resolve the "Server" adress, check the routing table for the corresponding device and extract the ip address....

Any thoughts on this? I hope this can be fixed, I find CSipSimple far superior compared to SipDroid.....

Comment #9

Posted on Jan 30, 2011 by Happy Bear

Well.. what about a combobox on preferences where you can choose the interface to use among the available network interfaces????

That would be easy and more versatile...

Comment #10

Posted on Jan 30, 2011 by Quick Hippo

Not sure that's the same problem. CSipSimple relies on pjsip which acts in the C stack. So applying the same patch is not possible as it. It has to be solved a clean way in the C stack.

However, to say the truth I didn't had a look to this issue yet. If anybody would like to contribute to the project on this point he will be welcome ;). But if I've time I'll do more tests and try to support VPN.

Comment #11

Posted on Jan 30, 2011 by Quick Hippo

@yuah : I don't think that's the problem. I think that all I need is to listen when VPN comes up and when up ask to pjsip to re-register.

Cause VPN is under the application layer. Pjsip acts on the native stack and does not bother with interface. It resolve the external IP using a much more clean way than what is done by sipdroid. (And for info, I started csipsimple cause sipdroid guys ignored my questions on the way they detect the public ip and as I had no reply... I started to search for another sip stack and found pjsip which is much more reliable ;) ... and start portage and application )

Comment #12

Posted on Jan 30, 2011 by Happy Lion

@yuah I personally feel that automatic resolving would be preferable, just because it just isn't a logical way to be forced to set the device for IP-probing... I mean, when this would be the problem, you can't expect an Android-user to know he/she should use the 'tun0' or 'rmnet0' interface as a mandatory setting. Maybe a combination ?? ;)

I think this would be a discussion for later... first, lets see if it's fixable without delving into the PJSip source. I hope that Regis (?) can cleanly fix it from within CSipSimple because that would yield the fastest results IMHO ;)

@R3gis.3R First of all, thanks for this amazing piece of software! If I had the skills to do so, I would be glad to contribute. Since my programming-skills are limited to Python, I think it's a fair bet to say I wouldn't be of any help in that area ;).

I checked the PJSip api and stumbled upon this: http://www.pjsip.org/pjsip/docs/html/structpjsua__transport__config.htm#a76cdb153b60fbbdbfd36ced9494bea0a. If I understand correctly, one can use the Transport-object to service one or multiple Accounts? Isn't setting public_addr attribute in the Transport class enough to advertise a specific IP as the origin/reply address?

And to be nostalgic; how does CSipSimple detect the public IP? :D

Comment #13

Posted on Jan 30, 2011 by Quick Hippo

@j.stam : first, if you know python, you can write in almost any other language ;) (I consider that's the master language ... somebody who codes python has the best skills to design the best apps... code less, do more :) ... I hate java and it's verbosity).

Then your right, there is an option in pjsip to configure public_address manually (if I do not mistake it can also be done per account directly). I can bind this setting in expert settings. The setting per account should already be set using expert account wizard and using "Force contact" field. But that's weird and not user friendly, I'd prefer to have a true auto-detection of the public IP, cause that's probably technically possible.

As for your last question : in fact it's pjsip that detect the "public IP". CSipSimple does only a weird and quick detection to detect if it should restart pjsip cause IP address has changed. I think that to fix this issue I have to fix that. (In fact I have to find a way to register to the fact VPN has been activated and then reload pjsip stack that will do the job automatically). Now, how pjsip do... well that's pretty complicated process (I'm not sure that I've understood everything cause I debug that long time ago and didn't dive deeper in the process than what I needed) : First it bind the server (open a socket). It read the local address on the open socket. At this point it knows the IP of the interface. That's pretty simple and extremely efficient. Doing that ensure to be safe to all strange routing rules. Cause that's up to the OS socket layer to resolve the route. Then reading the sock local IP is simple. So that's the first step, when first registering it send this IP. Then if you allow 'contact rewrite' (that's a trick used by pjsip guys), it deduce from result of the registration the public IP as seen by the server. In the OK to the registration the server replies with the IP it see for the client. If pjsip detect it is different from current announced IP it re-register with the new public address. That's a cool feature cause here no need of STUN or TURN. However some SIP server does not behaves properly regarding this method. And sometimes it's needed to tweak pjsip to change the way it re-register or to disable the feature.

Alternatively, it can use a STUN server. Here it simply ask the STUN server "what is my public IP?". If so it use provided IP address to register. The risk with that is to have the STUN server on another network than your SIP server. It occurs for enterprise IP-PBX when the STUN server is on public network and when you access to your enterprise IP-PBX from the local network... in this case obviously it's a bad idea to use the STUN server or you should have the STUN server on your IP-PBX/SIP server. It also occurs in some countries where the network is cut from the global network. For example if you are in China or Russia and try to use a STUN server in US or EU, and a SIP server in your country it will fail cause public IP seen by the STUN server is different from the public IP seen by the SIP server. And finally, there is TURN and ICE features. I'm not an expert about these features. But their aim is to resolve public IP too...

So that's pretty complex as you can see, but it never involve the interface. And that's a really good thing cause interface is just hardware and we should use OS features that abstract hardware for us ! :)

Comment #14

Posted on Feb 16, 2011 by Happy Bird

Not sure if it helps but I'm running CSipSimple with Android 2.3.2 on a Droid over OpenVPN without issue. The stock integrated SIP stack however won't connect over the VPN.

Comment #15

Posted on May 7, 2011 by Quick Hippo

Issue 718 has been merged into this issue.

Comment #16

Posted on Jun 3, 2011 by Quick Hippo

Issue 1015 has been merged into this issue.

Comment #17

Posted on Jun 3, 2011 by Massive Dog

I'm not sure whether to respond here, or in 1015, but I'm assuming if 1015 was merged here, I should respond here.

I have the VPN, and eth0 up, and Restarting the stack (going to settings and back) doesn't change the behaviour at all. Looking at the wireshark log of the packet, the packet comes from 10.8.0.13 (the vpn IP) to 10.8.0.1 (the vpn ip of the server), but in the sip register contact section, I get "[name]" instead of "[name]" . Because of the public IP in the contact section, the 200 OK response comes from the public IP of the server to the public IP of the phone. Sometimes this works, if they're actually real public IPs with no firewalling, but if you're in a random hotspot with a private IP, the 200 OK packet never makes it back to the phone.

Maybe the reason it doesn't work with force contact is because there's no way to put in the dynamic port # that pjsip happens to open for the connection (in the case above 38977), so Asterisk is trying to contact it at 5060, but pjsip is listening to some random port #.

I wonder if there's a way to tell Asterisk to ignore the contact IP, but use the packet IP instead?

There is still definitely a bug here somewhere, and it really needs to be fixed!

Comment #18

Posted on Jun 4, 2011 by Quick Hippo

Issue 833 has been merged into this issue.

Comment #19

Posted on Jun 4, 2011 by Quick Hippo

r902 (that will be built tonight), introduce a new receiver that ~should~ be aware about vpn connectivity changes.

As consequence it should at least restart the SIP stack when VPN connection is UP.

Then there is maybe remaining issue like the one of andrew about SDP and IP announced by pjsip to the remote party. If you are experimenting this case of problem, I'd be interested by logs (see HowToCollectLogs wiki page). With infos on the different IP that lives on your phone (if possible, or at least the VPN network address area).

Comment #20

Posted on Jun 6, 2011 by Massive Dog

at r905, still same problem, public IP in the contact field, I enabled logging, restarted the sip stack, and then stopped logging. Log sent now.

IP addresses should be pretty obvious, 10.8.x.x is vpn, 142.x.x.x is public. Those are the only interfaces that are up (besides loopback).

Andrew

Comment #21

Posted on Jun 6, 2011 by Massive Dog

Oh, I will add 10.8.0.1 is the server, 10.8.0.13 is the phone - 10.8.0.13 hardly even shows up in the log file.

Comment #22

Posted on Jun 8, 2011 by Quick Camel

Hi, i got exactly the same issue als Andrew.

The udp packets reach my asterisk server through vpn (server vpn ip 10.8.0.1) with correct source address (10.8.0.18), but asterisk tries to send packets back to the wrong contact ip (192.168.1.77 (wifi ip) in this case)

asterisk sip debug log:

<--- SIP read from 10.8.0.18:60027 ---> REGISTER sip:10.8.0.1 SIP/2.0 Via: SIP/2.0/UDP 192.168.1.77:60027;rport;branch=z9hG4bKPjYeJsxeETbjbLVuOsBXVFE4a8oBRW5iv4 Route:

HTH

Comment #23

Posted on Jun 8, 2011 by Quick Camel

It would be enough i think, if under "Force contact" one could supply an ip addres only (or interface name) and the dynamic port is added automatically.

Comment #24

Posted on Jun 8, 2011 by Massive Dog

The "Force contact" field does not work. In the contact info sent normally, there's the port number that pjsip has opened for incoming connections, and it is not 5060, and is random. If you omit the port number from the contact field, asterisk tries to contact the phone at 5060 when a call comes in (or similar), and pjsip isn't listening to that port, so nothing happens. The force contact field is on the right track, but there needs to be a way to tell it to append the port number to the forced contact address.

Comment #25

Posted on Jun 21, 2011 by Grumpy Wombat

Pardon me if this comes off as dismissive, but why should CSip need to be aware of a VPN at all? I have CSip running on two devices: a Xoom and a Nexus S, both via daemonized OpenVPN. Choppy sometimes, but my asterisk server is listening only on the private IP, and I was able to register without any problems at all. Whenever the VPN connects, my SIP registers.

Could anyone please explain to me: What is the logic of making CSip deal with the VPN directly? Isn't that what the OpenVPN client is for?

Comment #26

Posted on Jun 21, 2011 by Happy Bird

Josh - I'm running CSipSimple on a Motorola Droid with Android 2.3.2 over an OpenVPN network and like you, everything works fine. That wasn't the case with earlier versions of Android and some SIP clients still don't work with Android 2.3.2 over the OpenVPN.

For example, the stock integrated SIP capability won't work over the OpenVPN tunnel.
From thread posts I've read, it sounds like the non-working SIP stacks are sending all IP traffic over the Wifi or 3G (whichever is active) and ignoring the VPN.

Unrelated to this ticket but it would be nice if we could have CSipSimple auto-launch the VPN for making a call and then disconnect afterward. :)

Comment #27

Posted on Jun 21, 2011 by Massive Dog

Connect to your vpn from behind a NAT, then tell me og your sip still registers. Or, on your asterisk server, do a sip show peers. Is your phone registering with the vpn ip or the public one?

I am going to take a look at the code in a few weeks myself and just fix it, seeing as no one else seems to even get the issue.

Comment #28

Posted on Jun 22, 2011 by Grumpy Wombat

Escape: Thanks, that is exactly what I wanted to know. Andrew: "sip show peers" gives me the private (VPN) IP, as I expected it would. Is this undesirable?

It isn't exactly related to CSip, but is related to this thread, so I'll throw it out there in case it helps anyone add OpenVPN functionality to CSip: OpenVPN needs engine support in OpenSSL (AFAIK). I went through great pains to patch together a working version of OpenSSL suitable for use with OpenVPN. I'm not sure if you would have to do the same thing to add such support to CSip, but in case you do, I've put together a how-to for adding the engine support back into OpenSSL 1.0.0a (the version currently packed in AOSP). If anyone is interested, PM me and I will send you links and give explanations where they are needed so I don't further clutter this thread.

Thanks for all your hard work!

Comment #29

Posted on Jun 22, 2011 by Massive Dog

Yes, that is desireable. Hmm, why does it register with the VPN ip for you, but not for me? What revision are you running?

Comment #30

Posted on Jun 22, 2011 by Massive Dog

Yes, that is desireable. Hmm, why does it register with the VPN ip for you, but not for me? What revision are you running?

Comment #31

Posted on Jun 22, 2011 by Grumpy Wombat

Version of asterisk? Asterisk 1.8.4 built by joshl @ JoshAsterisk on a x86_64 running Linux on 2011-05-24

CSip? r933-tls

I have asterisk configured to only bind to the private (VPN) IP address. My thought process was to set CSip to use a private IP (or DNS that resolved to a private IP) and let the routing table do all the work of directing the packets over the VPN, which runs as a separate daemon.

Comment #32

Posted on Jun 22, 2011 by Massive Dog

Ok, my setup is slightly different. My Asterisk box has a vpn, and a regular interface, and stuff connects to it on both, so I can't limit it to only listen to the VPN IP.

I also thought that CSip would use the private IP, if I tell it to connect to asterisk on the asterisk server's private IP. The IP packet headers are actually correct, but in the SIP contact field, CSip puts in the public IP of the phone, and then asterisk switches to using that IP to talk to the phone. So from phone -> asterisk, it actually goes over the vpn, but from asterisk -> phone, it does not, it goes over the public network, so if the phone's "public" IP is actually behind a NAT, the connection doesn't work. Do you have something in your asterisk config (or do you know of a sip option) that makes asterisk ignore the sip contact field, and use the source IP address of the packets instead? I looked through all the sip options, I don't see anything like that at all.

The other funny thing is I swear, for a while, it actually randomly was working properly, until I rebooted the phone, and it seems the wifi became the first interface in the list or something again, and it switched back to using that IP in the contact field, instead of the VPN IP.

I have other asterisk servers that connect to this one over the same vpn, and everything works fine. All that traffic goes only over the VPN connections. I've also had desktop SIP phones connected over the same vpn as well (through a linux box at the other side being the VPN client and router), and that works fine too. The problem is just that CSipSimple picks the wrong IP address to put into the contact field when it registers. As I mentioned before, using the "force contact" field works, except then the port number (which is dynamic) is missing, and asterisk tries to contact CSipSimple on 5060, and CSipSimple isn't listening on that port. My plan was to just fix the code that does the "force contact" handling to properly include the port number, then it should work.

My asterisk is Asterisk 1.6.0.6.

I spent a few hours last night getting eclipse and the android SDK setup, and got CSipSimple checked out of svn last night, but I didn't get to the point of extraacting the pjsip library from the .apk file (I don't see a point in rebuilding it as I'm not changing pjsip), and thus never got the project to build yet. Just getting the environment took longer than I expected, but I did expect it to take a while - it always does getting a build environment setup.

Andrew

Comment #33

Posted on Jun 22, 2011 by Grumpy Wombat

Andrew, I just tried to PM you, but I can't figure out how to see your full email addy, and I am therefore not convinced that you can see mine. My last name is Lindsay, so I figure you can fill in the gaps and email me if you want to continue talking. For now, here is the link for patching the AOSP OpenSSL to accommodate OpenVPN. Not sure if you'll have to go this far, and most of it is probably OFN to you, but it may help: http://www.joshianlindsay.com/index.php?id=113

What is the extent of your control over the various parts of the system? If OpenVPN were to be integrated into CSip, would it be a separate package bundled in the same APK? I assume it would still be native.

I know just enough about asterisk to be a threat to my own sanity. So I intentionally setup my system to minimize complexity in that corner. I'm learning more about it each week as I have to deal with the NAT/SIP problem for other systems I work with. For what it's worth, my setup didn't have any problems with NAT/SIP for the reasons you mentioned. But it did require much more work at the handset.

Moderator, I won't be miffed if you nuke my posts. Sorry for cluttering your board. :-)

Comment #34

Posted on Jun 22, 2011 by Massive Dog

Yes, we can take this discussion offline...

I will send you an email.

Comment #35

Posted on Jun 22, 2011 by Quick Hippo

Moderator, I won't be miffed if you nuke my posts. Sorry for cluttering your board. :-)

Don't worry, that's fine :). Do not hestitate to share you findings. It is really welcome :D

About the fact to integrated OpenVPN to CSipSimple, I think that anyway it could/should remain two separate apk (in order to release it for mainstream users). I think that Android is enough well designed to allow apps to interact with each others - even for native library -. I'm currently trying to do something to allow an app to enrich native features of pjsip such as codec, video, TLS, ZRTP and so on from different apk. It should allow to add extras features dynamically and easily for mainstream users.

Comment #36

Posted on Jun 22, 2011 by Massive Dog

Yeah, I was also going to say, I don't see the need to integrate openVPN with CSipSimple. I'm running CyanogenMod. It has integrated OpenVPN support. I'm not sure if that's part of Android Gingerbread - I think it's their addon, but it's there, and all works right out of the box, so that wasn't my plan. I wonder if that has something to do with why it works differently for me than it does for you - OpenVPN is somehow setup differently in CyanogenMod than you have it setup... ? Hmmm...

Andrew

Comment #37

Posted on Jun 22, 2011 by Grumpy Wombat

CyanogenMod [...] has integrated OpenVPN support. Yes. The biggest obstacle to making it work is having a kernel with tunneling support, or the equivalent kernel module. Most of the carriers want this functionality removed, because then they can charge their customers for tethering support (which also relies on tunneling support). For the OpenSSL engine support, one could compile OpenVPN as a static binary and wrap a completely different version of OpenSSL into that. It makes the binary much larger, but it does the trick, and doesn't require that you replace your existing OpenSSL installation (which is otherwise adequate, IMO).

I'm not sure if that's part of Android Gingerbread It isn't. :-( However, I believe the source code that I used is very recently diverged from that which is in use by CM7. So for all intents and purposes, it can be treated the same.

So from what I gather from you guys, it would be better to extend CSip to manage OpenVPN. Currently, I simply start it as a daemon at boot time, and it connects opportunistically whenever the server's IP is accessible (ie, whenever a data connection exists). This works very well for my purposes because I only have one VPN that I care to use. But if I had several, a management app would be called for. I foresee myself writing one in the near future, and I plan to continue using CSip for VoIP. So let me ask you guys this:

How should CSip deal with OpenVPN? Should the user be able to bind different VPNs to different accounts? Should the VPN control feel like a global bolt-on, as the secure transport options presently do? What specific features are desirable?

Is it a bad thing if there exist features in CSip that require the phone to be (rooted and include busybox) in order to be used?

I'm willing to contribute to this project, because I get a large amount of utility from these tools. But if I'm going to spend the time to do it, I'd like it to be well done the first time.

Comment #38

Posted on Jun 22, 2011 by Massive Dog

I wish it would look at the server IP, and at the local interfaces, and if any of them happen to be on the same subnet, it should use the IP address of whatever interface that happened to be for the contact info. From previous discussion, this seems that it should be the job of pjsip, not CSipSimple, but it apparently doesn't work. The real solution is to fix it there, but for now, I'd be happy just kludging it in CSipSimple temporarily, for myself.

That would solve my simple problem, but would still leave a gap for someone with multiple VPN connections, and possibly connecting to things that are behind the VPN, not on the VPN itself. It seems there needs to be a way to tie a certain SIP account to a certain interface, or possibly group of interfaces. Then of course the next problem that comes up is with multiple VPNs, which order will they come up in? What if some are accessible and some not? Can (or should) one specify a unique interface name for each VPN, so regardless of order, or availability, VPN connection X always appears as interface tap / tun X? This is really a question for a VPN management app I guess, but needs to be considered in what the best way forward in CSipSimple is.

Andrew

Comment #39

Posted on Jun 23, 2011 by Massive Dog

Heh, now that I have the build environment all setup, ready to start making some code changes, and now it's connecting from the VPN IP - I don't get it. I'll have to check multiple times in the next few days if it continues to register from the correct IP. I seem to recall this happening before, then suddenly it stopped using the VPN IP. UGH I hate these kind of debugging problems - the intermittent problem is the worst to solve.

Andrew

Comment #40

Posted on Jun 28, 2011 by Massive Dog

Yup, and of course, now that I'm actually on vacation, it's back to it's usual tricks of registering with the wrong IP address again :(

Now I can try to change the code on my dev box remotely, or setup this laptop as a dev box (which I don't think is going to work well, as this machine is slow, and low on memory).

Could someone just change the code for the force contact so that it just replaces the IP address, but inserts the right port number on its own? Or is there some way I can force it to a certain port so that I can just type in a force contact myself and have it work?

Andrew

Comment #41

Posted on Jul 16, 2011 by Quick Monkey

My simple setup is as follows - I have a local Csipsimple account and an Openvpn tunnel. When I call another client direct via Openvpn tunnel (Openvpn tunnel provides several routes) Csipsimple reports the wrong address to the other client(Twinkle, testing zrtp).

Basically the correct behavior would be that when Csipsimple/pjsip starts or registers the accounts, it notes all the routes on the system (ip route) and all the interfaces and their addresses (ip addr). When a call goes out which happens to be with a destination address that routes out via a non-default interface, the call should be sourced with the address of that non-default interface (v4 or v6). This should work with multiple OpenVPN tunnels too.

My hunch is that to manage OpenVPN tunnels might be too awkward. Tunnels can fail and reconnect with a different address. I don't know if it's possible on Android but the best idea would be to get an triggered event when an interface changes and then accounts are re-registered.

Comment #42

Posted on Jul 16, 2011 by Quick Hippo

Ok, I'll try again to re-explain what should be "the correct behavior".

Keep in mind that pjsip is cross platform and that saying "detect system route" make absolutely no sense.

In fact what it does is much more simplier, when pjsip starts, it simply bind sockets to remote party and then automatically detect its "public" ip from the local part of the bound socket. Well what could break that : * use of stun * another account that get a route to public network and that starts before the vpn account. Both problem will be fixed when pjsip-2.0 will implement per account nat resolution (there is a tracking issue on this issue list about that). You can also disable stun,and disable "allow contact rewrite" for this account to avoid that.

That said, if pjsip starts when your VPN is up, it will work as expected. The public IP will be your IP in vpn network. It can't fail. It just about binding sockets, and if the core network layer of the system bind it correctly, I don't know why it would fail.

Then there is another problem... detect when VPN comes up. That's more complicated since there is no public API on android to know that. I recently added the most common interface (the one that is actually implemented in private api - I get that from AOSP source code to be notified when VPN network comes up and then restart the sip stack and re-register all accounts).

If it does not work, it means that the ROM you are using implements other way to notify application that VPN is up. If so, let me know, try to find infos about what intent I should listen and when I should restart, I'll add that, no problem :).

You can validate it comes from the fact it does not restart simply by manually go in settings and press back (closing settings view automatically restart the stack). If after that when your vpn is up it works, it's just about vpn up/down detection. If it still does not work, it's either about the fact the core network is not able to resolve correctly routing, or about the fact there is some stun feature or some other account that set up the global public IP of pjsip stack (and as I said, read and follow the issue 345 about that)

Comment #43

Posted on Jul 17, 2011 by Quick Monkey

Ok, I ran another test: For good measure I stopped all possible services on the android phone: Openvpn, CSipSimple. Btw, even though I stopped CSipSimple from Application Settings -> Running services when I logged in with root shell via adb, ps showed that 'com.csipsimple' was still there. I killed it to have it gone. Bottom line, at the start of the test nothing was running. I have only one local account configured in CSipSimple. Zrtp is turned on. No servers, no STUN, ICE or TURN. Absolutely no nat is involved in network configuration.

  1. Started the Openvpn tunnel. Tunnel came up, all good.

  2. Started CSipSimple.

  3. Made a call to the Twinkle client over OpenVPN. Call starts but Twinkle still reports that it comes from the address that's assigned to the Android phone wireless interface. Twinkle can hear audio from the phone, but the phone can't hear audio from Twinkle. Zrtp doesn't work of course. Tcpdump and tshark output shows that CSipSimple is reporting (in sip headers) its address to be the one from the wireless interface and Twinkle starts sending rtp to that address (unsuccessfully). In other words, port 5060 traffic itself is sourced and destined with the correct addresses, but address reported inside those packets (for rtp to work) is the wrong one.

What I am using: CSipSimple-r986-tls.apk from http://nightlies.csipsimple.com/tls/ Phone - Android 2.3.3, Kernel 2.6.29.6, CyanogenMod-7.0.3-Heroc (for HTC Hero)

Am I doing something wrong?

Comment #44

Posted on Jul 17, 2011 by Quick Monkey

Here's a paste of tshark dump on the first packet that goes from CSipSimple to Twinkle. http://friendpaste.com/JTl5Aj5Titoi9TCadFlns

Here's another paste of tshark dump on the first packet from CSipSimple to Twinkle. http://friendpaste.com/6Tcu8NQAq89PuX3KV0m2Rb This time around I changed Twinkle address to be different. But most importantly I chose the Expert Wizard and made sure Allow Contact Rewrite, Force Contact were set to the tun0 address and user on the phone. I also had to set Account id to something, otherwise Expert Wizard didn't allow me to save for local account.

The result is the same, Twinkle tries to send audio to the wireless address.

Comment #45

Posted on Jul 17, 2011 by Quick Monkey

Comment deleted

Comment #46

Posted on Jul 17, 2011 by Quick Hippo

If you want to be sure pjsip will not rewrite the contact header... you should disable "Allow contact rewrite" option and not leave it enabled. Is there another account enabled ? Also, what is really interesting is not the invite in this case, but what comes before. Trace from pjsip when it detect the public IP.

In your case it probably does before, for example while registering somewhere. So, traces from the software are much more relevant in this case to know what happens and why this "public ip" is used ;).

Actually if you really want to have a local account, a better idea would be to create a local account with the "local" wizard. If you do using the expert one, you must absolutely exactly know what you are doing, and you must know where you bind your local port of the client to set the account id to the correct thing. (for example, by default, if you don't change the local bound port, it is set to listen on random port, which mean that your local sip port is something random... and so it's hard to set in the account id ;) ).

Comment #47

Posted on Jul 17, 2011 by Massive Dog

So, rather than just mentioning binding the local port, and making it not random, how about actually saying how to do that?

Comment #48

Posted on Jul 17, 2011 by Quick Hippo

In expert settings mode (see wiki about that), in Settings > Network > UDP port. By default it's set to 0 (which mean random), set to 5060 if you want to set up local port to a fix port.

However, again, it's better to create a local account using local wizard if you actually want to create a local account. So I'd not advise to change the port but rather to use this local wizard instead (that's why I didn't entered details about this point !!).

Local wizard is the only wizard that is not an expert wizard behind the scene. It does something special in pjsip saying that this is a local account. As consequence, pjsip will automatically set the port of the account id with the one it has bound locally.

Just another point... actually what break up audio path is not the account / contact id. It's the info in the SDP.

But anyway, again, what is important to understand why pjsip choose this public ip, it's what happen before. Logs of pjsip are pretty clear about how it gets its public IP. And with limitation I previously explained (no per account NAT support), it should be possible to control (either if it's a local or a remote account).

Comment #49

Posted on Jul 17, 2011 by Quick Monkey

Is there another account enabled ? No. The local account is the only one. (I haven't set anything else up.)

I only changed the local account with the Expert Wizard for the last tshark dump. So all previous tests I did were with an account that was setup with the simple Local Wizard.

So I went to the CSipSimple settings and turned loglevel to 5. Then I shut it down, killed the remaining process via adb shell and turned on adb logcat. Then I started CSipSimple and here is the output for that:

http://friendpaste.com/27pPmU0RhSkkpkfsFV1Sdj

Somewhere in the middle it shows that pjsip chooses the wireless interface address for sip.

I'll be happy to help with any other testing.

Comment #50

Posted on Jul 17, 2011 by Massive Dog

Oh, ok, somehow I missed that UDP port number setting before (or I was never looking in "settings" but in the account settings). If I can force the port, then I can force the contact info field and just use that to get around the problem for now!

I still do have the dev environment setup, and will have a look at the code at some point and see if there's a better way to fix the problem, but this will be a quick fix in the meantime.

Comment #51

Posted on Jul 17, 2011 by Quick Hippo

Yes exactly.

@fossm : my bad : I forgot that, but when used as a local account, pjsip has no way to detect the correct public IP. The method described by Andrew is better if you'd like to have a local account. If you have a sip registrar on your vpn, pjsip will resolve the public IP correctly when registered. If not, you have to do the following (to sum up):

  • Setup the local UDP port of the app (Settings > network > udp port)
  • Create an expert account with a display name and setup as local id : you@YOUR_VPN_IP:UDP_PORT_OF_PREVIOUS_POINT.
  • disable "enable contact rewrite" in this case
  • normally it should not cry for any other missing params (else let me know, I'll fix that ;) ).

The reference in FAQ of pjsip may be helpful too : http://trac.pjsip.org/repos/wiki/FAQ#multihomed

Comment #52

Posted on Jul 17, 2011 by Quick Monkey

It's still not successful.

The only difference from your instructions was with setting up your local id; I had to put it in this format: '' I tried a different port also but that didn't make a difference. "Via" header in the packets still went with wireless address (but a correct port number). Connection information headers also have the wrong ip.

I restarted the app as always.

Would it be a good idea (or possible at all) for local account creation Wizard to have interface name field and force pjsip to use an ip like that?

Comment #53

Posted on Aug 21, 2011 by Massive Dog

I have finally gotten around to adding a forced bind address (per account, kindof), and IT WORKS! If I turn off the forced bind address, it tries to (incorrectly) use the 'public' ip address, and cannot register. When I put in a forced bind address, everything works correctly.

Before I release a patch, I'd like to get some feedback from other people, as well as the main developer as to what functionality would be useful, and some input on a few things.

Right now I have bind address and public address in each account, which allows each account to use a different interface if required. The bind address must be specified explicitly, which might be tricky if you have dynamically assigned VPN ips.

QUESTION 1: Would it be useful to be able to specify a wildcard in the bind address, and have csipsimple look at all the interfaces on the system, and match one to the wildcard? This way you could specify "bind to 10.8.0.x" and at runtime, csipsimple will figure out what the actual address in that range is and bind to it (or throw an error if there is no such interface up).

I haven't done any testing with more than one account active at a time. Essentially what I do is if the account is forcing UDP, and forcing a bind address, I remove the existing default UDP transport, and make a new one with the forced parameters in its place. This could severely break if you have multiple accounts active at the same time, and some of them are already using the default UDP transport. I'm guessing that if an account needs custom transport parameters, it would be better to just make a new transport for that account, and leave the default one alone.

QUESTION for the main developer: Do I need to remove a custom transport if the account later goes inactive?

QUESTION 2: Do people use multiple accounts active at the same time?

QUESTION 3: Would it also be useful to be able to force a port per account? This might be necessary if you need to know what port number each account is using on the csipsimple side, rather than having "custom" transports use a random address (as only one transport can use the default port, if specified, in the main settings).

Andrew

Comment #54

Posted on Aug 21, 2011 by Massive Dog

Oh, perhaps one problem I just discovered, when I build the app, I don't seem to get any audio to come out of the device anymore - the mic works fine, but nothing from the speaker. Don't know why yet.

Comment #55

Posted on Aug 21, 2011 by Massive Dog

Ugh, of course the problem is now the RTP transport still binds to the wrong address!!

GRRR, the PJSip stack sucks when it comes to multihomed boxes :(

Comment #56

Posted on Aug 21, 2011 by Grumpy Wombat

Andrew: Your audio problems are likely RTP related. Tell me: is the VoIP server under your control? If it is, I can give you help debugging.

To answer your question about multiple registrations: yes. Some users do register at multiple servers at the same time.

I can already force a port for a given account by appending ":" to the SIP registration address. Is this inadequate for some reason?

Comment #57

Posted on Aug 21, 2011 by Massive Dog

Ok, I fixed the RTP ip address issue now too. There is something seriously wrong with the way pjsip was designed!!!

Comment #58

Posted on Aug 21, 2011 by Massive Dog

In response to comment 56 by Josh:

That is the port you are connecting to on the server. I'm talking about the port that pjsip opens for the connections coming back to it. It can either be random (the way it is by default), or currently specified for all accounts in the application settings when you put it in expert mode. I thought it might be possible to specify which port was opened for each account (perhaps useful in registration-less setups), but now with this latest development with having to force the bind IP for the media transport too, and there can only be one media transport (it appears), really breaks being able to control all of this on a per account basis.

Looks like now that if you need to force the bind IP, it pretty much has to be a global setting that affects all accounts - a rather shortsighted design in the pjsip stack!

Each account is able to have a separate sip transport associated with it (UDP, TCP, TLS, etc), and when you create that transport, you can force what IP and port it is bound to (aka, to force to use VPN ip, the whole point of this issue). There is only one media transport though, and it applies to all accounts, so if you need to force a VPN ip on that transport, now all accounts have to use that transport. Either I'm missing something about how pjsip works, or that is not a very good design at all!

Comment #59

Posted on Aug 21, 2011 by Grumpy Wombat

I'm talking about the port that pjsip opens for the connections coming back to it. Ah. That makes sense now.

I haven't tried digging into PJSIP yet. I've been putting it off until last week when I started poking around in the java interface for it. So I probably can't help you too much there (yet). I was evaluating ZORK (which is built off PJSIP).

If you are testing your work with asterisk, you can restrict RTP ports to your clients, and even prevent them from trying to establish RTP connections directly to one-another (sip.conf => directmedia = no). This puts asterisk in the RTP audio path, and solved all of my NAT issues. It doesn't help your SIP problem, unfortunately, but it might make your life easier. I'm using the asterisk 1.8 branch.

Good luck. :-)

Comment #60

Posted on Aug 21, 2011 by Massive Dog

Yeah, the java front end on csipsimple is a bit complicated, and add in the wrapper around the pjsip library, and it takes quite a while to do some very simple things. Took me about 5 hours to generally figure out how it works, and figure out enough to add 2 settings to the expert account wizard for the bind IP and the public IP (and the database, and update the schema, and on and on), and probably another 3 or 4 to ponder how to actually implement it (per account, vs overall), and yet more to actually make it work.

I am using asterisk, and yes, I force all the RTP to go through asterisk. That combination, along with VPN connections, is extremely powerful and versatile!

Well, my problems are essentially solved now, what remains is to make it just a little more nicely implemented so it's useful to more people!

Comment #61

Posted on Sep 2, 2011 by Quick Rhino

i use freeswitch over vpn, im sure to nat everything on its way out of the phone (for layer3), and on the sip-side (application layer) freeswitch has it's own way to deal with nat... works fine =]

Comment #62

Posted on Sep 4, 2011 by Grumpy Rabbit

Hi andrew, in response to Comment 56:

i would highly appreciate that you release a patch as soon as possible, as i am traveling a lot and it would be a huge benefit for me, even if i would have to enter a new ip address each time. I used an iPhone before and this was exactely the way it was done in the SIP app there.

Question 1: A wildcard IP would be very nice, as for some reason i am unable to assign a fixed ip in my network but it is always in the same subnet.

Question 2: i do not

Question 3: see question 2

Brgds Fabio

Comment #63

Posted on Sep 4, 2011 by Grumpy Rabbit

Comment deleted

Comment #64

Posted on Sep 5, 2011 by Massive Dog

I will work on adding the wildcard for the IP address (just need to lookup how to get a list of active interfaces from android), and try to get a patch published as soon as possible (later today, or maybe tomorrow).

It's been working great for me - the odd time it spits up a message that it can't bind to that IP because no such interface exists (when the VPN disconnects), then when it reconnects, csipsimple registers on its own. It works quite well.

Andrew

Comment #65

Posted on Sep 7, 2011 by Grumpy Rabbit

Comment deleted

Attachments

Comment #66

Posted on Sep 7, 2011 by Grumpy Rabbit

Comment deleted

Comment #67

Posted on Sep 7, 2011 by Grumpy Rabbit

Hi Andrew,

as I am still highly interrested i wrote a function to get the VPN IP address. I use a wildcard on the interface name matching tun[0-9]. I think this is better than using the wildcard function on the ip. It works assumed the tun interface matches the naming convention tunX. Mine is name tun0.

Brgds Fabio

Attachments

Comment #68

Posted on Sep 7, 2011 by Massive Dog

Hi

Sorry for not getting the patch out sooner, but something came up (raid controller went berserk, working on getting a few TB of disk back online). I'll have a look at your code tonight hopefully. Last night I was looking at the java.net.NetworkInterface class on the android developer docs. Looks like it has pretty much anything needed!

Andrew

Comment #69

Posted on Sep 9, 2011 by Grumpy Rabbit

Hi Andrew,

could you maybe send me your changes via mail as far as they are? I've a bit time now to work on it.

Fabio

Comment #70

Posted on Sep 9, 2011 by Massive Dog

Sure, I was going to post a binary at least, as I'm not going to have time to work on it this weekend either, but I put a diff there as well.

http://www.ece.ualberta.ca/~hakman/CSipSimple

Andrew

Comment #71

Posted on Sep 9, 2011 by Massive Dog

Oh, and also, just so you know, there's a planned network outage where that's sitting tonight Sep 9th from 22:00pm to Sep 10th 7am MST (GMT -5), so if that link is unavailable tonight, that's why. It will be back when the network is back.

Andrew

Comment #72

Posted on Sep 9, 2011 by Grumpy Rabbit

Hi Andrew, thanks for sharing and great work! I had a look at your code. I see you force the bound and public address for pjsip. I read the documentation here http://www.pjsip.org/pjsip/docs/html/structpjsua__transport__config.htm#a76cdb153b60fbbdbfd36ced9494bea0a but i am not so sure what's the difference between public and bound address. However. don't you think it wouldn't be sufficient to just take the IP address of the tun Interface, set bound and/or public address (depending on whats really needed for a working OpenVPN connection) and create a switch like "Connect through OpenVPN" I see no clue in setting the whole ip stuff manually. OpenVPN uses tun Kernel module and I am pretty sure the interface is called /dev/tunX for all android devices.

Fabio

Comment #73

Posted on Sep 9, 2011 by Massive Dog

Yes, but I was thinking in the beginning that you could have multiple VPNs and multiple accounts, and hence would want to bind each account to a different interface, so the easiest way was to specify the ip address to bind to. Then when I was actually doing the pjsip part, I noticed that it seems you can only have one global media transport, so if you force the bind address for one account, all accounts now use the same media transport, so it's pretty useless for a multi account / multi vpn setup.

My way was more generic (if it was possible, which it seems not with pjsip the way it is), your way is easier!

The bind address forces which interface on the local device the socket will be bound to (for multihomed, like in our case the vpn vs wifi interface). The public IP is for publishing the ip address of a NAT router when you are behind it, and the NAT router is setup to forward all SIP traffic to you. So say the nat is 192.168.10.x, the phone has the address 192.168.10.2, and the router's public IP is 123.45.67.8, and the router is setup to forward all sip traffic to 192.168.10.2. You can't bind to 123.45.67.8 as that isn't a local interface on the device, but you do want to publish that as your contact address, as the router will look after getting the traffic to you. That's the purpose of the "Public" field. It isn't useful to me (as the VPN eliminates all the NAT entirely), but I figured I'd add it at the same time. Might be useful for some.

Andrew

Comment #74

Posted on Sep 10, 2011 by Grumpy Rabbit

Hi Andrew,

i tested your patch yesterday. I set the bound_addr to my vpn ip and left the public_addr unset. Seems to work pretty good! Very fast connecting and good audio. I implemented this for me hardcoded, just to act like this: Is there a openvpn interface? if yes: set bound_addr to vpn ip if no: leave everything as it is I thought about creating a checkbox in expert mode but i am pretty sure as this is only a temporary fix as long as there is no clean way of openvpn support, its better to leave it like this without database changes for easier patching against never revisions. You can find binary and diff here: http://lombardi.mobi/csipsimple/

Greets Fabio

Comment #75

Posted on Nov 7, 2011 by Quick Hippo

Andrew and Fabio thanks a lot for the patches, sounds great.

Sorry for the big delay. I'll include this setting in the future dev release (based on psjip-2.0) that will now support bind and pub uri a better way. It will also has per account transport creation for media which should be better. :)

So it will be integrated really soon. Before, I'll do a stable release without the fix, and then it will be integrated with your modifs. It's indeed a good idea to add a checkbox in expert mode to use bound_addr as the vpn iface if available and add the bound_addr as an editable entry if this checkbox is not activated.

Comment #76

Posted on Nov 11, 2011 by Happy Bear

@35, 37

How ought one frame a question to hosted PBX providers to solicit what info they need to modify their PBX asterisk flavors to reduce the masochism of sip/rtp conveyed solely through openvpn on same serv server to android client (whose phone 3g/4g is suffering carrier Nat, where both the IP address, public interface/private interface, change frequently, seemingly to break such uses even when attempting to hold open with keep alive). Verizon Wireless.. does offer static IP address on 3g/4g interface

Comment #77

Posted on Jan 14, 2012 by Quick Hippo

rtp_bound_address (and public address but should be optional in vpn case) are now part of the latest nightly build's expert wizard settings.

Once I'll release my other project to automatically turn on or off settings (in this case csipsimple account config) based on conditions (in this case vpn connectivity). It will allow to have some complete solution.

For now, with the account config + home screen widget it should at least allow to workaround.

Comment #78

Posted on Jan 25, 2012 by Happy Wombat

Fabio the link you provided in comment 74 is not longer valid. Can you please provide a new one in order to download the apk? Thanks a lot in advance.

Comment #79

Posted on Feb 3, 2012 by Swift Horse

Can you explain how that option works? I tried to insert my VPN IP, but this did not work, on asterisk the IP that appears is always that of 3g or wifi connection

Comment #80

Posted on Feb 3, 2012 by Massive Dog

Hi

You need to give a bit more information about your setup to figure out what your problem is. The IP you put into "Bind address" and or "Public address" is the IP of your tun/tap interface on the phone. This forces the SIP stack to use that interface, so the source address in the IP headers should be that IP, and hopefully the "contact" IP in the SIP headers will also contain that IP. If that's what you're doing, and it's not working, you will probably need to have a look at the SIP packets with wireshark to see what's going on. If the IP headers contain the right source address, but in the SIP packets the "contact" ip is wrong, you might have to use the "force contact" field as well. Since I added the "Bind address" and "Public address" fields, I have not had to use "force contact" - for me, it always comes out with the right IP on it's own - no guarantee that that happens always though.

Also, I have not tried any recent nightlies that have incorporated my patch, I'm still using the original APK I made when I first added those features. Somewhere further up this bug thread, I posted a link to that APK - as a last resort, try to use that version and see if it works.

Andrew

Comment #81

Posted on Feb 4, 2012 by Massive Rabbit

Hallo,

I have the same problem. I use OpenVPN and csipsimple always uses the wrong IP adress. I currently use the nightly-build from 14. January. Before I tried the latest nightly build, but it also didn't work. My mobile phone has on the vpn the ip 192.168.177.110. My sip-server has adress 192.168.178.1. A route is set up (I can ping the mobile device via the .110 adress from my home network), I am very expirienced with OpenVPN so there is no mistake. I set up this 192.168.177.110 adress the two options "RTP bound address". But it still doesn't work. Then I set up "RTP port" to 39999 and under "force contact rewrite" I had the contact plus this port, but then my SIP server tells me that it couldn't establish a connection on that port. I also tried another port, didn't work, too. Wireshark tells me taht csipsimple still tries to go via the adress from the wrong network interface. Wireshark log:

Via: SIP/2.0/UDP 10.175.17.218:60236;rport;branch=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Max-Forwards: 70 From: "622" ;tag=xxxxxxxxxxxxxxxx To: "622" Contact: "622"

So obiously in the Via and Contact Headers is the wrong IP.

Would be great if you can fix this, than csipsimple is the first good VOIP client that works correctly (sipdroid doesn't support ilbc so that isn't a good VOIP client to me). If you need forther information, please don't hesitate to ask.

Thanks for your help.

Comment #82

Posted on Feb 5, 2012 by Massive Dog

If you try to connect without the VPN connection setup, do you get "Failed to create transport Cannot assign requested address" and "Failed to create media transport Cannot assign requested address"? If not, then it's not doing what I intended it to do, and maybe the patch got changed somehow in the latest nightlies. Also, the settings involved (at least in my version - maybe not in the nightlies) are under account settings (have to be in expert mode) Bind Address and Public Address. Do not force contact rewrite, and do not set the "RTP Bound address" - I'm not even sure where that setting is, unless the text got changed for my setting names.

Can you try my version of the apk? It's here (just the same as in comment 70 in the bug thread)

http://www.ece.ualberta.ca/~hakman/CSipSimple/

That version works perfectly for me, and is my original changes, so if that works, and the nightlies do not, then that's something you need to report back to the bug, so that it can be fixed.

Andrew

Comment #83

Posted on Feb 5, 2012 by Quick Hippo

In nightlies it's also in expert wizard mode. It's almost same changes than yours Andrew. The biggest difference is that it's now based on pjsip-2.x so I didn't applied it strictly, but the idea is the same. I also added some new options about QoS and all changes of pjsip-2.x as account options.

Also as far as I understood, pjsip-2.x now start the media transport only when it's needed (just before the call is established).

Comment #84

Posted on Feb 5, 2012 by Massive Dog

I will give the latest nightlies a short sometime when I have time to muck around, and see if they work for me. Perhaps later today, but possibly not too!

Andrew

Comment #85

Posted on Feb 7, 2012 by Massive Rabbit

With the latest nightly, there is no option "Bind Address" and "Public Adress". Neither in Account-Settings nor in expert sip account settings (also tried with trunk 1247). There are only those to "RTP Bound Address" options.

@Andrew: I've tried your version already before, but it didn't work. I left public adress empty, because a) I only have one 10.x.x.x adress and b) this changes very often, so I can't specify this one. I've only setup "bind address" and there I set up 192.168.178.110, but it also registers with the 10.x.x.x address. I tried your version now again, but it is same negative result. Routing from the mobile phone seems to be correct, because there is a datastream from csipsimple to 192.168.178.1 of about 4 KB/s (ilbc-Codec), so that works. But because it registers with the 10.x.x.x adress and so no audio comes back from the sip server.

If I open CSipSimple without established OpenVPN-Tunnel it just can't register, there's a timeout, but thats obvious because 192.168.178.1 can't be reached. If I register and then cut the VPN it tries to establish the call as before, but after ~30 seconds it gives up and ends the "call" (andrew's version). r1247 nightly tells me after a few seconds that connection has been lost and handover is not yet supportet and call screen stays.

Forgot to mention in my post from the 4. february, that CSipSimple works when I route the whole traffic through the VPN, so sip account data, codecs and so on are correct. But routing the whole traffic is no option for me. In German IP-Phone-Forum there is another user with the same problem and routing the whole traffic through the VPN also works with that user.

Hope you can fix this very soon.

Comment #86

Posted on Feb 7, 2012 by Quick Hippo

The name is just different but it's RTP Bound address ;).

In fact there is several different point. I think that what we could advise for the first setup is to have address set by a DHCP that always assign same IP address to same device (based on mac address). At least for the first step it will help a lot.

Then there is several things to check.

The first thing is the contact used to register. Usually this is not so important if the "contact" field is not properly registered because the socket between sip server and csipsimple should not be cut. So the server will always be able to announce an incoming call. It can become more annoying when announcing the ip of the device to the remote party and can lead the remote party to be unable to send the ack. In this case, your will observe an established call that never gets confirmed (and the app will end the call about 30s later).

To fix this part, it's about fixing the "contact" field. There is several things to check/try to configure properly. The first thing that could definetly solve the problem is to have a STUN server on the LAN of your sip server. This is the best and faster solution. The application will ask your stun server for it's "public" ip. And your stun server will reply from the LAN point of view what is your public IP. It will also help for the media part. http://sourceforge.net/projects/stun/ It's pretty easy to install. That's what I use when I've a NATed LAN topology. (We can consider the VPN as a NATed subnetwork of your LAN). In this case, you only need to configure the stun server. Then bad side is that for now pjsip does not support per account STUN server. So it force you to have your stun server dns resolved both on public and private. But that's something that can be done if you have a complete control on your network and SIP server.

If you are not able to install a stun server somewhere on your sip server lan. You'll have to understand how settings works for contact field in csipsimple. The first thing to know is that there is a "force contact" field that may allow to force what is announced by csipsimple to be the contact sip uri (with the ip of the device). Obviously in this case you have to know what will be the public ip of the device. So I do not advise to use this way. Then the app is able to auto detect the ip. This first thing it does, it's binding your server. Thanks to the fact the socket will be bound to the server using linux socket layer, it will be able to retrieve the address of the interface used (local ip address) to bind the server. It's the address of the local interface that bind the sip server. It will first register with this address. Then, if you activated the option "Allow contact rewrite" it will look at the reply of the register from the server. The sip server can inform about the sip address it can see from its point of view. When "allow contact rewrite" is enabled, the application will then take into account this information and send a new registration (with an inline unregister -- you can use legacy unregister if sip server does not support that). In case of sip server that manage sbc, it can lead to mess up the sip server and this option has to be disabled. In other cases it can helps to register with the correct ip address. Also, once pjsip get this ip, it consider it as the public ip.

That's for the "Contact" header field.

With that done and properly registered on your server, you'll have to check now the media ip. The one that will be used to establish media path between the two clients. In this case, stun can also help.

Here comes the RTP public address (there is a name problem in the nightly I've just fixed it ;) -- but it's the first one) and the RTP bound address. The RTP public address is the address that will be sent in the SDP by the application to announce the remote party where to send media. Obviously it needs the device IP and port mapping to be fixed. This one is about the announce that is done to remote party. Normally it's autodetected by the application, but again in some network topology there is no ways to find it out. (and again, stun is a good solution for finding that out). The RTP bound address is the ip address of the local interface you want to force the app to use for media. About these two options, you can have a look here : http://www.pjsip.org/docs/2.0-alpha2/pjsip/docs/html/structpjsua__transport__config.htm

I hope that these explaination enlights a little bit things. Normally in your case, it's really about configuration. SIP protocol is not really done for NATed network when used alone. To solve this problem they introduced STUN (and many other techniques). It's always very tricky to configure and really depends on sip server and topology. The behavior of csipsimple is very configurable due to the fact I try to give access to all field of the sip stack so that you should be able to configure it for your needs provided the fact it's technically possible to do so. I mean, if the sip stack is never able to get the media ip/port it will never be able to send a correct information to the remote part and media path will be wrong.

I repeat myself, but in your case, I think that it's more about a NAT problem than about the fact it's VPN. I think that with a wifi hotspot that create a NAT network under your LAN, you'll get exactly the same problem. So you should consider solve the NAT issue first before thinking about VPN stuff. And the easiest way is to have your own STUN server as you have your own SIP server.

Comment #87

Posted on Feb 7, 2012 by Massive Dog

seeing as you're playing around with vpns and advanced sip stuff, I'm assuming it would be no problem for you to give the output of

busybox ifconfig

when your vpn is connected?

I'm not clear whether your vpn is routed or bridged as well - that would also be useful to know.

Andrew

Comment #88

Posted on Feb 7, 2012 by Massive Dog

also, ifconfig output of your openvpn server, and your asterisk box would also be useful. Obfuscate any public ip's if you're worried about that - all that's really important is the vpn and private networks.

Andrew

Comment #89

Posted on Feb 7, 2012 by Massive Dog

The whole point of the VPN is it takes NAT out of the equation. With a VPN, you should have only 2 networks that you care about, and both use normal routing (or switching, in the case of a bridged vpn) to pass traffic between them, not NAT. There should be a) the network the sip server resides on (typically private, but it doesn't make any difference as long as the VPN server knows how to contact it), and b) the VPN network (which is almost always private, but again, not really important).

If setup correctly, all machines on either of those 2 networks can ping machines on the other one, and there is no NAT involved, just simple routing. No truly "public" IPs should be involved anywhere, just the IP of the VPN client, and the IP of the SIP server. All the NAT nastyness is hidden behind the VPN connection, which only uses one port, and thus is easy to get through NAT, or almost any other kind of stupidity one encounters at random public internet connections.

Because of this, I don't think the issue is NAT based, but rather something to do with how the ip addressing of the internal vs vpn network is setup, or incorrect subnet masks, or something similar, which is why I'd like to see how the interfaces are configured on the various machines.

To that end, the output of

route -n (or busybox route -n possibly on the phone - I don't remember whether the native Android one works properly or not - I know the native ifconfig on Android prints nothing, and you need to use the busybox version to actually see what's important)

on the various boxes would also be quite useful

Andrew

Comment #90

Posted on Feb 7, 2012 by Massive Rabbit

Thanks for your detailed reply. You're posting faster than I can analyse and write :). I think there is some misunterstanding with NAT, so I'll try to explain. I have a 2 Point VPN and my mobile phone always gets 192.168.177.110. This Adress is directly routet to my home network (192.168.178.0/24) without any NAT in between. Its routed to have less overhead, not bridged. The 10.x.x.x private adress is from my provider and their DHCP. They perform NAT for my Internet Connection. On that 10.x.x.x interface there has to be only the VPN data and no data from CSipSimple (except encapsulated in the VPN of course). So I think a STUN-Server in my network would not really help. My SIP server is a AVM Fritzbox and there I see detailed Internet-Call Log settings. There is the 10.x.x.x IP where it tries to send the RTP datastream. I use the same setup with x-lite softphone from my notebook and the same VPN Tunnel (then it is deactivated on the mobile phone) and everything is fine. Even the internet comes via Tethering from my mobilephone. It also works with Sipdroid on the mobile phone (but then only in HSDPA networks because of the lack of ilbc). So I doubt that it is a NAT problem. The only difference between the two OpenVPN configs is one line "redirect-gateway def1" than it works.

I've already tried the force contact field header with IP adress 192.168.177.110. Then my fritzbox tried to connect to that IP, but now the port is the problem. I tried 39999 and set this as "RTP Port" but then my fritzbox showed in the log that it couldn't connect to port 39999. I've also tested another Port with the same negative result.

CSipSimple sends the data out on the right interface, otherwise their wouldn't be ~3-4 KB/s traffic on the VPN, but no data comes back, there isn't even a dialtone, which comes when I redirect all traffic through my home lan (see above).

"Then, if you activated the option "Allow contact rewrite" it will look at the reply of the register from the server. The sip server can inform about the sip address it can see from its point of view. When "allow contact rewrite" is enabled, the application will then take into account this information and send a new registration (with an inline unregister -- you can use legacy unregister if sip server does not support that). In case of sip server that manage sbc, it can lead to mess up the sip server and this option has to be disabled. In other cases it can helps to register with the correct ip address."

That sounds interessting and I verified it. When I have disabled "Allow Contact Rewrite" then csipsimple registers only with my 10.x.x.x adress. When I enable it csipsimple reregisters with the correct 192.168.177.110 adress. I have to use the legacy unregister, otherwise I have "2 bindings". However I often get an error "Bad request" I have to reregister, than it works, but thats not so important.

However I now found the problem. I focused to much on the SIP register part only. SIP always worked, meaning that incoming calls were always displayed at my mobile phone, so the correct IP-adress had to be in the contact field that it worked.

I examined the SIP invite packet and there is the problem. In the SDP header there is "Owner/Creator, Session Id (o): - 3537609596 3537609596 IN IP4 10.170.62.128 Session Name (s): pjmedia Connection Information (c): IN IP4 10.170.62.128"

then a few lines below "Connection Information (c): IN IP4 10.170.62.128 Media Attribute (a): rtcp:40001 IN IP4 10.170.62.128"

So there is the problem. When I use "redirect-gateway" then there is the correct 192.168.177.110 address in this fields and then calls work. No we are on the right way to solve that problem.

If you still need some outputs from my various device, please tell and I'll give you. I have fritzbox, VPN-Server (with IP Routing between Fritzbox and mobile phone) and my mobile Phone. But I'm sure that there is no misconfiguration with routing because I'm using OpenVPN for years now.

BTW: I noticed, that CSipSimple does not display SIP error codes, espically "busy here" is not shown, instead the call is just ended. Please fix that, too.

Comment #91

Posted on Feb 7, 2012 by Quick Hippo

Well, it really depends on your VPN configuration. On comment #85 and #81 I see that b6140296 use 2 differents network address plan (192.168.x.x and 10.x.x.x). I use to see this kind of configuration when there is some NAT on the middle (usually on the VPN server). And also it's the default behavior if the route to the VPN subnetwork is not set on gateway of the sip server network. -- Also, what is important in this case is that the sip server can route to the sip client --

But you're right, it could be a little bit fast assumption. However, it could also explain why it does not work with your version either ;). So for b6140296 I think that it would be a good idea to check that first. In case of a routing/switching configuration sip client must be able to ping sip server (usually obvious) but also sip server must be able to ping sip client (less obvious).

But indeed, if that's a simple routed network as in your case, NAT stuff are not relevant.

And as I said at the very begin, normally VPN should not really be a problem from pjsip point of view. But possibly android (or alternative ROM) mess up things in the middle so that the linux native socket layer is lost trying to open sockets. So the workaround to force using an interface is needed. I think that it's not required on all ROM, because on my device it worked flawlessly (no config needed at all) with a VPN lab I made at home. The hardest thing to do was to configure the network topology properly.

Comment #92

Posted on Feb 7, 2012 by Quick Hippo

Oups, didn't see your comment before posting :) Ok so I misunderstood your problem.

Comment #93

Posted on Feb 7, 2012 by Quick Hippo

Well sounds you find the reason :)

Sounds it's the same problem than Andrew finally. It's about the RTP bound address/port. By default pjsip will bind 0.0.0.0 and listen everywhere. To announce in the SDP pjsip use the default gateway to choose the highest score interface. In your case if "redirect-gateway" is not enabled, the stack will consider that a remote party is more likely to use the interface that has gateway. And so will announce with 10.x.x.x in your case.

In order to solve that : the RTP bound address. It will force the RTP transport to bind only the interface you specify and so, it will announce the correct one in SDP :) (it should ;) ).

So, even in this case, STUN could be useful. Normally media plan and control plan are not linked in SIP. Pjsip guys try to respect that I think. That's why the RTP address is not linked to the SIP address. Sipdroid does a lot of crappy things. Maybe pragmatic... but that are not necessarily in line with SIP RFC. You could have a look to the issue about pbxes.org (the company behind sipdroid) and TCP. They have a very pragmatic approach (also very pragmatic for their service ;) ), so sometimes it can lead to have something working easier.

Also, side note, even in this case, a STUN server could help. As it will inform pjsip of the ip/port seen from the sip server it may be very useful (even if no NAT ;) ). Since STUN is common to control and media plan it can be used by the stack to find out the ip/port independantly and cleanly without making any assumption on the fact control plan and media plan must use the same path.

Comment #94

Posted on Feb 7, 2012 by Quick Hippo

Last point about the topic, one related issue in pjsip project : https://trac.pjsip.org/repos/ticket/11

Even if probably a good solution on android would be to configure the account on the fly using a plugin to csipsimple depending on network connectivity (because android APIs gives more infos).

Comment #95

Posted on Feb 7, 2012 by Massive Rabbit

When it is the same problem than Andrew, I wonder why his version does not work with me. I use Android 2.3.6 (since today) and before I tried with Android 2.3.4.

RTP bound adress does not work for me, sadly. The question is why. Perhaps I configuread it wrong. In the field RTP bound adress (both), I set "192.168.177.110", without the quotation marks, of course.

I'd like to avoid a stun server, I prefer using the RTP-bound adress. Since my VPN adress stays the same, that should be no problem. Next question is why does X-Lite work on the laptop, there is a similar situation.

Comment #96

Posted on Feb 8, 2012 by Massive Dog

I really don't know why my APK wouldn't work for you, because that's the same issue I had initially. CSipsimple (or rather pjsip in the background) kept binding to the wrong interface, so I added the fields to be able to force it to bind to the VPN interface.

It's strange though that when you use my apk, you don't see the error messages popping up I do if the VPN interface just ins't up. It should definitely be throwing up an error about "cannot bind to interface - doesn't exist" (or whatever the exact text was I mentioned initially). Do you possibly have more than CSipSimple installed at once somehow? I don't think that should be possible, but I can't see how it can do what it's doing for you, unless the wrong code is being executed somehow.

The "rating" algorithm that pjsip uses to pick which interface to bind to is just really wrong. From what I can tell, it almost always picks the default gw, even if there's a better match (IP wise) available. But yet in some cases it seems to work, and others, it just doesn't at all. I have a feeling in the cases where it "works" and people are using VPNs, it really isn't using the VPN at all, but things are managing to connect because of STUN, or something similar, so it just works, and people don't notice.

Either that or in some stock Androids, I think the providers have mucked with the network stuff to try to get you to not be able to tether the phone for free, or use VPNs over their network or something. What Android are you running? Stock, or a open source build, or what? I'm using Cyanogen (mostly because of it's built in openVPN functionality out of the box - not that compiling that into any kernel is that hard. Even with Cyanogen, I have an alternate kernel I compiled for when I need USB host support on the phone).

Andrew

Comment #97

Posted on Feb 8, 2012 by Massive Dog

Just for info, I'm using Android 2.3.3 with kernel 2.6.37.4-cyanogenmod-82245-g7f230e8

Comment #98

Posted on Feb 8, 2012 by Massive Rabbit

I have Counterpath Bria also installed, but it was not running when CSIPSimple was running. I have now setup the Stun-Server from Sourceforge (link some posts above) and now everything works. Thank you. I thought that would be more difficult. However I don't understand why the Stun-Server insists on 2 network-interfaces and with binding to 0.0.0.0 it really won't work, you have to specify the IP of your interface you want it to bind. You can specify only the IP-adress of your interface and everything works, eventhough the Stun-Server tells you Stun won't work because you haven't specified a second IP.

I'm using this http://www.android-hilfe.de/original-firmwares-fuer-samsung-galaxy-s/188200-firmware-2-3-6-29-12-2011-i9000xxjvu-value-pack-odin-root.html version. You don't have to build your own tun.ko module or kernel. I just use this one http://forum.xda-developers.com/showthread.php?t=793712 and everything is fine. It worked with 2.3.4 and now with 2.3.6. I also have another tun.ko (don't know anymore where I got that from) but that also worked with 2.3.4, didn't test it yet with 2.3.6. So it is not necessary to build your own tun.ko.

BTW: I've also tried Cyanogen, but I didn't like the userinterface.

Comment #99

Posted on Feb 9, 2012 by Quick Hippo

@b6140296 : About stun server, I was also a little bit surprised that it requires two interface. One works pretty well. I think that there is some parts of the STUN specification that can't be implemented with only one interface, but as far as I can tell having only one is enough for simple needs.

@andrew : I think that's a complicate debate to say what should be the good interface to choose. I think that one important point is to ensure that the app consider media and control network plan as independent plans. For example, you can consider a network topology where you have Client 1 -----<>Server Client 2 -----<>Server And for the voice path Client 1 ----- Client 2 This topology should not be avoided in SIP protocol. SDP is about negotiating media and from an abstract point of view it should not take into account the control plan.

Then, all is about how the sip stack decide which interface it chooses to announce. I agree with you that the way it's chosen by pjsip is maybe not the best way from a pragmatic point of view in our case. As far as I understood this rule : http://trac.pjsip.org/repos/wiki/FAQ#multihomed applies. So indeed, it's more likely to choose the interface on which there is the gateway with this algorithm . Also, I think that I didn't reproduce the issue because on my VPN lab I use the VPN to get out : all traffic was going out through the VPN. There is as many VPN topology as simple private network topology ;).

Then about how legitimate this algorithm is, I reasonably can't judge. I'm far to be a SIP expert -I leave all that stuff to pjsip guys-; In this specific case, their algorithm is not a good idea. But we can't exclude that there is other cases where it's not a good idea to announce in SDP the interface used for control plan. At least, doing this the way pjsip does is not something wrong regarding SIP RFC - from my understood-. Besides, something to be aware of is that pjsip stack is not a monolithic sip stack. It's modular with different parts and the one responsible of media negotiation is different from the one in charge of call control. It allows projects (such as blink and sflphone if I don't mistake) to use a different media stack with more features (desktop sharing).

Maybe pjsip guys could provide more information about this choose and an option to use the same interface than the one used for control plan would be a good idea. I'll do some investigation in pjsip source code to see if there is something simple for that. And then ask on pjsip mailing list.

If you want to get more info or ask directly pjsip developers, you can directly ask them here : http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Maybe you will have better arguments than me and will explain it better ;) - as you probably notice, English is not my native tongue ;)

Comment #100

Posted on Feb 13, 2012 by Grumpy Rabbit

Hi,

i haven't read this thread for a while. During a web server upgrade i forgot to upload my patches on the new server. Here are my patches and the apk again. http://lombardi.mobi/csipsimple/

Be advised, this apk is based on trunk of september.

Comment #101

Posted on Feb 13, 2012 by Grumpy Rabbit

I've just tested the apk with my configuration at home. (Asterisk 1.8 Server) First step: Just create a basic account to connect to asterisk in home network via wifi. If this works: Login in any other Network (Wifi 3g or whatever) Then Connect to home network via OpenVPN. Now csipsimple should be able to connect again.

System Configuration tested: Android 2.3.6 (CheckROM RevoHD V4) OpenVPN 2.1.1 static binary Asterisk 1.8.7

Comment #102

Posted on Aug 17, 2012 by Quick Hippo

(No comment was entered for this change.)

Comment #103

Posted on May 13, 2013 by Quick Rhino

if you could give us a cli command to restart pjsip, then we could simply call that in a script using --up in openvpn

Comment #104

Posted on May 13, 2013 by Quick Hippo

You need to send an broadcast intent (and the app doing that must have correct android permissions to do that). You can see the api of csipsimple here : http://r3gis3r.github.io/SampleCSipSimpleApp/javadoc/ (and the action of the broadcast intent to send : http://r3gis3r.github.io/SampleCSipSimpleApp/javadoc/com/csipsimple/api/SipManager.html#ACTION_SIP_REQUEST_RESTART)

Status: Fixed

Labels:
Type-Enhancement Priority-Medium