Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPv6 support #6

Open
mkubecek opened this issue Jun 5, 2015 · 28 comments
Open

Add IPv6 support #6

mkubecek opened this issue Jun 5, 2015 · 28 comments

Comments

@mkubecek
Copy link
Collaborator

mkubecek commented Jun 5, 2015

No description provided.

@mkubecek
Copy link
Collaborator Author

mkubecek commented Jun 8, 2015

The networking code is in much worse shape than I expected - IP addresses and ports kept and passed as hardcoded long and short (in host byte order) all around the place. A cleanup will be necessary to be able to start with IPv6, it's going to take some time and careful testing. All in all, this should defintely not block the first Qt4/Qt5 based release.

@LubosD
Copy link
Owner

LubosD commented Jun 29, 2015

Personal note - how to indicate both IP4 and IP6 in SDP: https://lists.cs.columbia.edu/pipermail/sip-implementors/2007-May/016579.html

@LubosD
Copy link
Owner

LubosD commented Jun 29, 2015

It seems the idea is that if IPv6 is used to contact the SIP server, then IPv6 is to be used for SDP and consequently RTP. Alas, I cannot find any public SIP servers with IPv6.

@mkubecek mkubecek self-assigned this Jul 18, 2015
@sdgathman
Copy link

Dropping this note as I am searching for another IP6 SIP client that supports peer to peer.

For me, the killer application of SIP with IPv6 is peer to peer mode. There is no need for SIP servers when you dispense with IP4 and the %^$#&*% NAT. I am using linphone for peer to peer calls, but the configuration is very fragile. For instance, if it doesn't find an IPv6 default route, it thinks "network is inaccessible" . (It is common to use 2000::/3 for IANA ips and IP6 VPNs will use a subnet of FC00::/7.)

Linphone refuses to believe that an IP6 VPN IP is a real reachable IP - unless I tell it "Behind NAT gateway with this public IP" (even though IP6 doesn't need or in most cases have NAT).

Anyway, a peer to peer VPN SIP address looks like this:

sip:username@[fcba:e4bd:848c:31ad:ce90:1f89:7907:1521]

Those are just as convenient as any other SIP address when added to an addressbook/contacts.

Peer to peer is especially powerful when using an end to end encrypted VPN with authenticated IPs like Cjdns. The above is a Cjdns IP - it is the double sha512 hash of the public key. So you know your calls are end-to-end encrypted and not MITMed. There is no central IP assignment and no VPN concentrator.

@sdgathman
Copy link

It seems the idea is that if IPv6 is used to contact the SIP server, then IPv6 is to be used for SDP and consequently RTP. Alas, I cannot find any public SIP servers with IPv6.

SIP server? Where we're going, we don't need SIP servers! (Or STUN servers.)

@4-FLOSS-Free-Libre-Open-Source-Software
Copy link
Contributor

issue is open since 2015 nowadays more and more SIP servers Support IPv6. Still would be nice future feature.

@vanrein
Copy link

vanrein commented Apr 29, 2022

And baresip 2.0.2 supports IPv6 properly. (Older versions, like the one I found in Debian stable, do unlogical things such as trying to respond to IPv6 offers with an IPv4 counterpart.)

There is an RFC detailing the transition,
https://datatracker.ietf.org/doc/html/rfc6157

I've skipped Twinkle for quite a while because it does not handle IPv6, but I really thought it was a pitty. I agree that, given IPv6 support, it is possible to dial directly between phones or, which is my purpose, between domains. Telcos are an optional extra for those with nostalgic tendencies. And wiretapping by media gateways can also be avoided without such gateways. Passive observation of traffic passing by can also be avoided because SDP (with an SRTP key in it) may be encrypted if it does not need to give in to rewriting by NAT traversal helpers. There are plenty of reasons to make IPv6 possible in a SIP phone. (In general, IPv6 blooms in peer-to-peer protocols, and always leaves IPv4 use cases behind. IPv4 is the model of the world that needs central servers to bring users together. This is not a perfect model of the Internet and its supposed freedom, I suppose.)

I've setup a structure for an IPv6-only SIP server in Kamailio. Its local accounts work, and can call back and forth,
https://gitlab.com/arpa2/mkroot/-/blob/master/contrib/sip-trunk/etc/kamailio/siptrunk.cfg.in

@fbriere
Copy link
Collaborator

fbriere commented May 6, 2022

Thanks @sdgathman and @vanrein for helping me better understand the usefulness of this feature. (Since I, like many people, don't actually use IPv6, this was not exactly at the top of my priority list.)

Still, this looked like an interesting challenge, so I've spent the last week working on this. While I've cleared most of the hurdles so far, I'm currently blocked by a big one that has got me quite stumped, so I'm still uncertain on whether or not this is actually doable. We'll see how it goes from there.

@fbriere fbriere assigned fbriere and unassigned mkubecek May 6, 2022
@fbriere
Copy link
Collaborator

fbriere commented May 6, 2022

The networking code is in much worse shape than I expected - IP addresses and ports kept and passed as hardcoded long and short (in host byte order) all around the place.

Man, that's the easy part! 😏 (Long and tedious, sure, but not very complex.) Then you've got addresses passed as strings, sometimes empty, sometimes set to 0.0.0.0 (which may or may not be equivalent), or 255.255.255.255 (also used as a placeholder for other purposes).

While the assumption throughout the code that everybody speaks IPv4 is an issue, the most problematic is the assumption that everybody speaks the same protocol (whether IPv4 or v6). This results in us crafting a SIP message (with our local IP address in it) in one part of Twinkle and passing it to the networking part along with a list of destination addresses. This works fine if we only stick to IPv4 (or v6), but mixing them both results in two messages, and each recipient must be sent the right one according to their address. I fear I'll have to dig deep to figure out a solution for this one.

@sdgathman
Copy link

mixing them both results in two messages
How about generating a structure/array with two messages to pass to the networking part - and pick the right one for each recipient? :-)

@fbriere
Copy link
Collaborator

fbriere commented May 7, 2022

How about generating a structure/array with two messages to pass to the networking part - and pick the right one for each recipient? :-)

Yeah, that's actually the approach I'm going for, but it's far easier said than done, trust me. 😄

@vanrein
Copy link

vanrein commented May 9, 2022

[...] the most problematic is the assumption that everybody speaks the same protocol (whether IPv4 or v6).

Yes, that is the most difficult part. Generally it should be safe to stick with the same protocol once it has been used. So an INVITE over IPv4 can be handled completely over IPv4, and an INVITE over IPv6 can be handled competely over IPv6. Likewise, for outgoing traffic, you can make a choice based on DNS addresses (preferring IPv6 to avoid NAT traversal issues I suppose) and stick with it.

This works fine if we only stick to IPv4 (or v6), but mixing them both results in two messages, and each recipient must be sent the right one according to their address.

The golden path is indeed to be flexible, and follow along when the other changes AF, with SIP over IPvN and RTP over IPv(10-N). You could offer flexibility of that kind if you are able and willing, by sending both IP4 and IP6 offers in SDP. When the other side has sent an SDP offer, you are probably best off making a choice (and then certainly IPv6 is helpful to avoid single-sided calls).

I fear I'll have to dig deep to figure out a solution for this one.

Talk, and ask, if you need help.

Meanwhile, I have a tool SIPproxy64 now closing in on 1.0 release that might be useful. This is a proxy that sits between IPv4-only and IPv6-only elements, mirrorring back and forth. Purpose is to use IPv4-only hardware phones in an IPv6 environment (such as the entire Internet, domain-based calling). It is run near one's IPv4 elements, so it does not crossover NAT. Actually, SIPproxy64 is a kind of NAT, except that it pokes out to to world using IPv6 so there's only firewall transition, not 3rd-party, SIP-unaware address translation.

I also have older work named 6bed4 which is a tunnel mechanism that makes IPv6 available everywhere, and otherwise creates an instant tunnel. The Internet Draft for 6bed4 was designed with SIP phones in mind, and the ability to assume IPv6 with remote parties. That could work in a SIP phone even in environments that cannot even use something like free IPv6 tunnels via 6in4.

This work was funded by NLnet 10 years ago. They might also be interested in seeing Twinkle moving this way.

@vanrein
Copy link

vanrein commented May 9, 2022

It seems the idea is that if IPv6 is used to contact the SIP server, then IPv6 is to be used for SDP and consequently RTP. Alas, I cannot find any public SIP servers with IPv6.

SIP server? Where we're going, we don't need SIP servers! (Or STUN servers.)

  1. Formally, SIP server is the side that answers to a transaction like INVITE, so it is an end point in its UAS role. When it initiates a transaction like BYE, it takes on a UAC role. The role changes per transaction, and dialogs ("phone calls") have transactions to mark changing moments. This is nitpicking, but it may be the reason why you cannot find any.
  2. What you are looking for is called a SIP proxy. And a widely open one is Kamailio. It has had a lot of work done on it, as it is used by all sorts of telecoms operators. (Sometimes under older names, OpenSIPS, OpenSER, SER.) Much of the SIP proxy world is pretty much convinced to flexible open source software.

@vanrein
Copy link

vanrein commented May 9, 2022

(It is common to use 2000::/3 for IANA ips and IP6 VPNs will use a subnet of FC00::/7.)

+1 on the importance of this family of addresses.

  • fc00::/8 is used for administratively allocated numbering schemes.
  • fd00::/8 is used for randomly filled numbering schemes.

These addresses are not fit for global routing, and in some places that is a strength. They are 192.168./16 or the IPv6 world, except that nobody in their right mind should try translating them to routable addresses. That makes them better, in some ways :)

It is quite possible to use fc00::/8 for a group of friends or inside a company, fd00::/8 is a popular choice in peer-to-peer networks, where they might add 56 bits of a public-key derived hash as an insecure hint towards the owner of a remote party with a given public key.

IP4 and the %^$#&*% NAT

+1 on the strong words, except that NAPT is to blame, not NAT without port translation. It ports that jump all over the place that break the peer-to-peer idea(l)s. It has long been my goal to go IPv6-only, and I am now developing the containers to make this possible for SIP, including PSTN trunking.

Pardon my enthousiasm. I've waited 10 years until IPv6 finally grew up :-) and Twinkle back then was at its end, and not going to do this.

@fbriere
Copy link
Collaborator

fbriere commented May 10, 2022

The compromise I'm seriously considering would be to limit each SIP message (or transaction, or dialog, depending on what Twinkle's code will allow) to only one IP version.

Basically, when a FQDN resolves to both IPv4 and IPv6 addresses, only the v4 ones would be retained, and the v6 ones would be ignored. (I'd favor this order as the default to avoid the usual "things break when IPv6 is enabled" issues¹, though I suppose there should be a user-profile option to switch it around.) IPv4-only and IPv6-only hosts (including bare IP addresses) would therefore not be affected.

While not a perfect solution, this would certainly lift a huge boulder off my shoulders. Are there any objections?

¹ Don't count on AI_ADDRCONFIG to solve this. It certainly does nothing for me.

@fbriere
Copy link
Collaborator

fbriere commented May 10, 2022

You could offer flexibility of that kind if you are able and willing, by sending both IP4 and IP6 offers in SDP.

You can't offer both IP4 and IP6 for the same media stream in standard SDP. Although there are extensions which aim to achieve this (ANAT (obsolete), ALTC (informational only) and ICE (complex as ****)), we can't always expect our peer to understand them. (Heck, Twinkle itself doesn't, and probably won't in the near future.)

So, "4 with 4" and "6 with 6" it will be.

When the other side has sent an SDP offer, you are probably best off making a choice (and then certainly IPv6 is helpful to avoid single-sided calls).

Since we don't support the previously-mentioned add-ons, we don't have any choice and must abide to whatever is in the offer. At least this makes things simple. 😄 (Though I'll have to remember, if we ever get an IP6 offer via IPv4, to check whether or not we have IPv6 connectivity before accepting.)

@fbriere
Copy link
Collaborator

fbriere commented May 10, 2022

(I'd favor this order as the default to avoid the usual "things break when IPv6 is enabled" issues¹, though I suppose there should be a user-profile option to switch it around.)

On further examination, this would probably need to be a global system setting. (That's not where it should be, but I don't think I'll be able to shoehorn it into a user profile without breaking the whole carton of eggs.)

@vanrein
Copy link

vanrein commented May 11, 2022

This makes sense, especially the last one about preferences. Twinkle could be used on a mixed network but connected to an IPv6-only telephony service.

  • (X) Prefer IPv4 (welcome IPv6 peers)
  • ( ) Prefer IPv6 (welcome IPv4 peeers)
  • ( ) Only IPv4 (ignore/reject IPv6 peers)
  • ( ) Only IPv6, (ignore/reject IPv4 peers)

The default should be one of those "Prefer" I think, and which is a matter of taste (where one's taste is likely to develop over time).

If you want to go for extra mileage, you might consider these settings separately

  1. for each registered account separately, to represent the account's RTP proxying abilities
  2. for direct traffic to sip/s:[email protected] peers

Thank you for working on this! I would love to be able to use Twinkle again (and advise it to friends).

@fbriere
Copy link
Collaborator

fbriere commented May 12, 2022

Oh, great. It turns out that, despite all appearances, ccRTP never properly worked with IPv6 in the first place; no progress has been made since partial support was added back in 2006. 😞

This is actually what prompted SFLphone (now Jami) to drop ccRTP back in 2015. (Thus leaving Twinkle as its only remaining user, and making it even less likely that further development will ever take place.)

Bummer.

I suppose the next course of action would be to do like Jami and replace ccRTP with something else; I'll eventually create a separate issue to look at the alternatives. In the meantime, don't hold your breath for a quick resolution, as the bar has now been raised by several notches. ☹️

@vanrein
Copy link

vanrein commented May 12, 2022 via email

@vanrein
Copy link

vanrein commented May 26, 2022

I'm starting to feel that this discussion is ending on too-much-work due to the ccRTP stack.

Is it an idea to invite the people from this project, and/or related GNU projects, to this discussion and ask them for input? The things being discussed here are usually very motivating for people who embrace the GPL, and it might help them find the motivation to (re)start this work on ccRTP.

It's sad if an underlying library stagnates progress towards online freedom, because it gives an impasse to the layers built on top of it. But if the people who built the underlying library are aware of this it may bring the project back to life.

I sent an email inviting a small number of people from GNU and ccRTP to this issue.

@sdgathman
Copy link

sdgathman commented May 26, 2022

One work around is to use NAT64 to map an internal private IP to a public IPv6. But this requires a way to tell the SIP engine about the public IPv6 the ip4 is mapped to - i.e. a UI configuration thing. (Or even just a poor documented line in the text config file added with an editor for proof of concept :0) )

@vanrein
Copy link

vanrein commented May 27, 2022 via email

@sdgathman
Copy link

I've never actually had to implement NAT64, generally installing tunnels/vpn to bring IPv6 to IP4 only networks and ditching IP4 only apps. So I greatly appreciate your detailed description from experience on why that was probably for the best - despite losing my favorite VOIP desktop app, twinkle.

@vanrein
Copy link

vanrein commented May 30, 2022 via email

fbriere added a commit to fbriere/twinkle that referenced this issue Jun 8, 2022
Any migration towards IPv6 (LubosD#6) will require identifying all IP
addresses currently represented as `unsigned long`.  To this end, we now
change their type to one of two newly-introduced `typedef`s:

 - `IPaddr` for IPv4 addresses in host byte order
 - `IPNaddr` for IPv4 addresses in network byte order

(This also happens to fix a few instances where `unsigned int` was
erroneously used.)
@vanrein
Copy link

vanrein commented Jun 11, 2022

The discussion of Path MTU discovery in Kamailio came to an interesting conclusion:

  • Always set socket option IPV6_MTU_DISCOVER to IPV6_PMTUDISC_WANT on IPv6 sockets, to learn about Path MTU problems.
  • To avoid (a limited number of) timeouts while learning Path MTU, that is for perfection for UDP/IPv6, set socket option IPV6_RECVERR at level SOL_IPV6 and detect ICMPv6 "Packet too Big" returns immediately via recvmsg() with MSG_ERRQUEUE. Existing resending practices may however suffice.

@vanrein
Copy link

vanrein commented Sep 19, 2022

I tried a few angles to tickle the RTP people, and clearly nothing was the result.

Is it a wild idea to not depend on abandonware and move to a mature alternative?

Then, you might want to look into the libraries underneath baresip,

  • libre for realtime audio handling with a high level of standards compliance
  • librem for higher-up media handling (but that would add functionality that you are not relying on now, I think)
  • baresip as an example implementation using these libraries

My suspicion is that you would end up mostly removing code, and doing a very big cleanup.

I continue to believe that this project needs IPv6 but am aware that this is an opinion, and therefore personal. But every phone software that holds back the shift to IPv6 represents a user base that is incompatible with free, direct media flows. This means continued care for remote parties who yet have to mature, and falling back on IPv4 as a terrible default platform. And though baresip is a wonderful alternative, not everyone will want to reserve a terminal for their phone.

@vanrein
Copy link

vanrein commented Sep 19, 2022

As an entrance point, the redemo project and specifically its user agent demo give an idea of the work involved. Plenty of callbacks to work with.

I had to look a bit for documentation, but found Doxygen annotations inside the source code of the libraries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants